https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121533

            Bug ID: 121533
           Summary: False positive with
                    -Wanalyzer-use-of-uninitialized-value on direct
                    assignment of calloc's result when optimisation is
                    disabled
           Product: gcc
           Version: 15.2.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: Chris.Bazley at arm dot com
  Target Milestone: ---

With the command line option -fanalyzer, GCC 15.2.0 generates a false positive
when translating the following program:

#include <stdlib.h>
#include <stdint.h>

int main(int argc, char *argv[static argc + 1])
{
  (void)argv;
  size_t height = argc, width = argc * 3;
  double (*(*data)[height])[width] = malloc(sizeof *data);

  for (size_t i = 0; i < height; ++i)
  {
#ifdef WORKAROUND
    double (*p)[width] = calloc(width, sizeof(double));
    (*data)[i] = p;
#else
    (*data)[i] = calloc(width, sizeof(double));
#endif
    if (!(*data)[i]) return 1;
  }

  double d = height && width ? (*(*data)[0])[0] : 0;
  (void)d;

  for (size_t i = 0; i < height; ++i)
    free((*data)[i]);

  free(data);
  return 0;
}

See https://godbolt.org/z/E8fhzf5jh

The compiler's output is:

Using built-in specs.
COLLECT_GCC=/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/bin/arm-unknown-linux-gnueabihf-gcc
Target: arm-unknown-linux-gnueabihf
Configured with: /opt/.build/arm-unknown-linux-gnueabihf/src/gcc/configure
--build=x86_64-build_pc-linux-gnu --host=x86_64-build_pc-linux-gnu
--target=arm-unknown-linux-gnueabihf
--prefix=/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf
--exec_prefix=/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf
--with-sysroot=/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot
--enable-languages=c,c++,fortran,ada,d,objc,obj-c++,go --with-arch=armv7-a
--with-fpu=neon --with-float=hard --enable-__cxa_atexit --disable-libmudflap
--enable-libgomp --enable-libssp --enable-libquadmath
--enable-libquadmath-support --enable-libsanitizer --disable-libmpx
--with-gmp=/opt/.build/arm-unknown-linux-gnueabihf/buildtools
--with-mpfr=/opt/.build/arm-unknown-linux-gnueabihf/buildtools
--with-mpc=/opt/.build/arm-unknown-linux-gnueabihf/buildtools
--with-isl=/opt/.build/arm-unknown-linux-gnueabihf/buildtools --enable-lto
--enable-threads=posix --enable-target-optspace --disable-plugin --disable-nls
--enable-tls --disable-multilib
--with-local-prefix=/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot
--enable-long-long --with-mode=thumb
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 15.2.0 (GCC) 
COLLECT_GCC_OPTIONS='-fdiagnostics-color=always' '-g' '-o' '/app/output.s'
'-fno-verbose-asm' '-S' '-fanalyzer' '-v'  '-mfloat-abi=hard' '-mfpu=neon'
'-mtls-dialect=gnu' '-mthumb' '-mlibarch=armv7-a+simd' '-march=armv7-a+simd'
'-dumpdir' '/app/'

/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/libexec/gcc/arm-unknown-linux-gnueabihf/15.2.0/cc1
-quiet -v <source> -quiet -dumpdir /app/ -dumpbase output.c -dumpbase-ext .c
-mfloat-abi=hard -mfpu=neon -mtls-dialect=gnu -mthumb -mlibarch=armv7-a+simd
-march=armv7-a+simd -g -version -fdiagnostics-color=always -fno-verbose-asm
-fanalyzer -o /app/output.s
GNU C23 (GCC) version 15.2.0 (arm-unknown-linux-gnueabihf)
        compiled by GNU C version 16.0.0 20250802 (experimental), GMP version
6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.19-GMP

GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory
"/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot/include"
#include "..." search starts here:
#include <...> search starts here:

/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/15.2.0/include

/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/15.2.0/include-fixed

/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/15.2.0/../../../../arm-unknown-linux-gnueabihf/include

/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot/usr/include
End of search list.
Compiler executable checksum: 99a8b0e275c3e0bba54d1a44bc537082
<source>: In function 'main':
<source>:21:41: warning: use of uninitialized value '*data[0]' [CWE-457]
[-Wanalyzer-use-of-uninitialized-value]
   21 |   double d = height && width ? (*(*data)[0])[0] : 0;
      |                                  ~~~~~~~^~~
  'main': events 1-4
    8 |   double (*(*data)[height])[width] = malloc(sizeof *data);
      |                                      ^~~~~~~~~~~~~~~~~~~~
      |                                      |
      |                                      (1) region created on heap here
    9 | 
   10 |   for (size_t i = 0; i < height; ++i)
      |                      ~~~~~~~~~~       
      |                        |
      |                        (2) following 'false' branch (when 'i >=
height')... ─>─┐
      |                                                                        
       │
......
      |                                                                        
       │
     
|┌───────────────────────────────────────────────────────────────────────────────┘
   21 |│  double d = height && width ? (*(*data)[0])[0] : 0;
      |│             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |│                                                |
      |└───────────────────────────────────────────────>(3) ...to here
      |                                                 (4) following 'true'
branch... ─>─┐
      |                                                                        
          │
  'main': events 5-6
      |                                                                        
          │
     
|┌──────────────────────────────────────────────────────────────────────────────────┘
   21 |│  double d = height && width ? (*(*data)[0])[0] : 0;
      |│                                 ~~~~~~~^~~
      |│                                        |
      |└───────────────────────────────────────>(5) ...to here
      |                                         (6) ⚠️  use of uninitialized
value '*data[0]' here
COMPILER_PATH=/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/libexec/gcc/arm-unknown-linux-gnueabihf/15.2.0/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/libexec/gcc/arm-unknown-linux-gnueabihf/15.2.0/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/libexec/gcc/arm-unknown-linux-gnueabihf/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/15.2.0/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/15.2.0/../../../../arm-unknown-linux-gnueabihf/bin/
LIBRARY_PATH=/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/15.2.0/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/lib/gcc/arm-unknown-linux-gnueabihf/15.2.0/../../../../arm-unknown-linux-gnueabihf/lib/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot/lib/:/opt/compiler-explorer/arm/gcc-15.2.0/arm-unknown-linux-gnueabihf/arm-unknown-linux-gnueabihf/sysroot/usr/lib/
COLLECT_GCC_OPTIONS='-fdiagnostics-color=always' '-g' '-o' '/app/output.s'
'-fno-verbose-asm' '-S' '-fanalyzer' '-v'  '-mfloat-abi=hard' '-mfpu=neon'
'-mtls-dialect=gnu' '-mthumb' '-mlibarch=armv7-a+simd' '-march=armv7-a+simd'
'-dumpdir' '/app/output.'
Compiler returned: 0

Adding -DWORKAROUND to the command line so that the return value of the call to
calloc is assigned to an intermediate variable before being assigned to
(*data)[i] makes the problem go away: https://godbolt.org/z/x47PG3dE4

Adding -O to the command line without the workaround also makes the problem go
away: https://godbolt.org/z/dqeaTqM3j

Setting argc to 1 on entry to the main function has also been observed to make
the problem go away: https://godbolt.org/z/oqhf6xzxP

Unfortunately I was unable to create a simpler test case.
The system type was AArch32 ARM but it makes no difference.

Reply via email to