https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120802
Bug ID: 120802 Summary: Erroneous warning, -Warray-bounds, on accessing memory returned from a function declared with the alloc_size attribute with int pointers on optimisation -02 and above. Product: gcc Version: 14.2.0 Status: UNCONFIRMED Keywords: diagnostic, false-positive Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: gizanuru404 at gmail dot com Target Milestone: --- Host: x86_64-linux-gnu Target: x86_64-linux-gnu Build: x86_64-linux-gnu Created attachment 61699 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=61699&action=edit gcc intermediate file of the MRE In the code shown below, the allocating function (declared with the "alloc_size" attribute) allocates a block of memory large enough to hold the struct and an array of integers. When I try to access the memory 8 bytes into the block (size of the struct on my machine) with an "int pointer" I get an erroneous "-Warray-bounds" warning when compiling with "gcc version 14.2.0" and options "-O2 -Wall". Other diagnostic options, as suggested on https://gcc.gnu.org/bugs, such as "-fno-strict-aliasing -fwrapv -fno-aggressive-loop-optimizations -fsanitize=address,undefined" do not make a difference. A minimum reproducible example: ``` struct my_arr { int *arr; }; void *xmalloc(const long int size) __attribute__((alloc_size(1))); struct my_arr *my_arr_alloc(const long int len) { struct my_arr *ma; const long int arr_size = sizeof(*ma->arr) * len; ma = xmalloc(sizeof(*ma) + arr_size); ma->arr = (int *)(ma + 1); ma->arr[0] = 0; return (ma); } ``` The verbose gcc command line output: ``` gcc -v --save-temps -O2 -Wall -c gcc-alloc_size-error.c Using built-in specs. COLLECT_GCC=gcc OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 14.2.0-4ubuntu2~24.04' --with-bugurl=file:///usr/share/doc/gcc-14/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,m2,rust --prefix=/usr --with-gcc-major-version-only --program-suffix=-14 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/libexec --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-libstdcxx-backtrace --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-14-ig5ci0/gcc-14-14.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-14-ig5ci0/gcc-14-14.2.0/debian/tmp-gcn/usr --enable-offload-defaulted --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2 Thread model: posix Supported LTO compression algorithms: zlib zstd gcc version 14.2.0 (Ubuntu 14.2.0-4ubuntu2~24.04) COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O2' '-Wall' '-c' '-mtune=generic' '-march=x86-64' /usr/libexec/gcc/x86_64-linux-gnu/14/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu gcc-alloc_size-error.c -mtune=generic -march=x86-64 -Wall -O2 -fpch-preprocess -D_FORTIFY_SOURCE=3 -fasynchronous-unwind-tables -fstack-protector-strong -Wformat-security -fstack-clash-protection -fcf-protection -o gcc-alloc_size-error.i ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/14/include-fixed/x86_64-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/14/include-fixed" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-linux-gnu/14/include /usr/local/include /usr/include/x86_64-linux-gnu /usr/include End of search list. COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O2' '-Wall' '-c' '-mtune=generic' '-march=x86-64' /usr/libexec/gcc/x86_64-linux-gnu/14/cc1 -fpreprocessed gcc-alloc_size-error.i -quiet -dumpbase gcc-alloc_size-error.c -dumpbase-ext .c -mtune=generic -march=x86-64 -O2 -Wall -version -D_FORTIFY_SOURCE=3 -fasynchronous-unwind-tables -fstack-protector-strong -Wformat-security -fstack-clash-protection -fcf-protection -o gcc-alloc_size-error.s GNU C17 (Ubuntu 14.2.0-4ubuntu2~24.04) version 14.2.0 (x86_64-linux-gnu) compiled by GNU C version 14.2.0, GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.26-GMP GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: 0a1f5636be17fb23bc53f873c9a9b227 gcc-alloc_size-error.c: In function ‘my_arr_alloc’: gcc-alloc_size-error.c:22:16: warning: array subscript 2 is outside array bounds of ‘struct my_arr[1]’ [-Warray-bounds=] 22 | ma->arr[0] = 0; | ~~~~~~~^~~ gcc-alloc_size-error.c:19:14: note: at offset 8 into object of size [0, 8] allocated by ‘xmalloc’ 19 | ma = xmalloc(sizeof(*ma) + arr_size); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O2' '-Wall' '-c' '-mtune=generic' '-march=x86-64' as -v --64 -o gcc-alloc_size-error.o gcc-alloc_size-error.s GNU assembler version 2.42 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.42 COMPILER_PATH=/usr/libexec/gcc/x86_64-linux-gnu/14/:/usr/libexec/gcc/x86_64-linux-gnu/14/:/usr/libexec/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/14/:/usr/lib/gcc/x86_64-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/14/:/usr/lib/gcc/x86_64-linux-gnu/14/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/14/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/14/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-save-temps' '-O2' '-Wall' '-c' '-mtune=generic' '-march=x86-64' ``` I discovered a few things while investigating: 1. The warning is triggered for options -O2, -O3 and -Os. Other lower optimisation levels don't trigger it. 2. The warning is only triggered for only a few types of the pointer in the struct, for example int and short int pointers triggered the warning while char and long int did not. 3. The warning is only triggered if the xmalloc function accepts a long int parameter and not triggered if it is unsigned or a shorter width type like int.