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.