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.
  • [Bug c/120802] New: Erroneous wa... gizanuru404 at gmail dot com via Gcc-bugs

Reply via email to