When compiled with -O3, the following code produces an "array subscript is above array bounds" warning, which is bogus as far as I can tell: #define MAX_VAL 16 typedef struct { int itemList[MAX_VAL+1]; unsigned int numItems; } ItemList; void FrobList(ItemList *l) { unsigned int i; for (i=0; i < l->numItems-1; i++) { int minVal = l->itemList[i]; unsigned int minIdx = i; unsigned int idx; for (idx=i+1; idx < l->numItems; ++idx) { if (l->itemList[idx] < minVal) { minVal = l->itemList[idx]; minIdx = idx; } } l->itemList[i] = l->itemList[minIdx]; } } $ gcc -O3 -Warray-bounds -c LmiH264RefPictures-Reduced.c LmiH264RefPictures-Reduced.c: In function ‘FrobList’: LmiH264RefPictures-Reduced.c:18:19: warning: array subscript is above array bounds [-Warray-bounds] if (l->itemList[idx] < minVal) { ^ The warning occurs on compilers targeted to x86_64 and armhf, but not i686. It does not occur with -O2 or lower. Tested on both Linux and Cygwin. This is a regression from GCC 4.6.3, at least. Have not tested 4.7.x. Clearly it would be an out-of-bounds access if l->numItems were >= MAX_VAL+1, but (in the actual application this testcase is reduced from), it's an invariant that it won't be, and the compiler shouldn't be making range assumptions to the contrary. Verbose compiler output: $ gcc -v -O3 -Warray-bounds -c LmiH264RefPictures-Reduced.c Using built-in specs. COLLECT_GCC=gcc Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) COLLECT_GCC_OPTIONS='-v' '-O3' '-Warray-bounds' '-c' '-mtune=generic' '-march=x86-64' /usr/lib/gcc/x86_64-linux-gnu/4.8/cc1 -quiet -v -imultiarch x86_64-linux-gnu LmiH264RefPictures-Reduced.c -quiet -dumpbase LmiH264RefPictures-Reduced.c -mtune=generic -march=x86-64 -auxbase LmiH264RefPictures-Reduced -O3 -Warray-bounds -version -fstack-protector -Wformat -Wformat-security -o /tmp/ccXMNHkF.s GNU C (Ubuntu 4.8.2-19ubuntu1) version 4.8.2 (x86_64-linux-gnu) compiled by GNU C version 4.8.2, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu" ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../x86_64-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-linux-gnu/4.8/include /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed /usr/include/x86_64-linux-gnu /usr/include End of search list. GNU C (Ubuntu 4.8.2-19ubuntu1) version 4.8.2 (x86_64-linux-gnu) compiled by GNU C version 4.8.2, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1 GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 Compiler executable checksum: dc75e0628c9356affcec059d0c81cc01 LmiH264RefPictures-Reduced.c: In function ‘FrobList’: LmiH264RefPictures-Reduced.c:18:19: warning: array subscript is above array bounds [-Warray-bounds] if (l->itemList[idx] < minVal) { ^ COLLECT_GCC_OPTIONS='-v' '-O3' '-Warray-bounds' '-c' '-mtune=generic' '-march=x86-64' as -v --64 -o LmiH264RefPictures-Reduced.o /tmp/ccXMNHkF.s GNU assembler version 2.24 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.24 COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/ LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../:/lib/:/usr/lib/ COLLECT_GCC_OPTIONS='-v' '-O3' '-Warray-bounds' '-c' '-mtune=generic' '-march=x86-64'
Confirmed. The first revision to trigger the error is r192990 (gcc 4.8.0) so marking this a regression.
Author: msebor Date: Thu Nov 16 16:48:36 2017 New Revision: 254833 URL: https://gcc.gnu.org/viewcvs?rev=254833&root=gcc&view=rev Log: PR middle-end/63477 - Bogus warning with -O3 -Warray-bounds: array subscript is above array bounds gcc/testsuite/ChangeLog: PR middle-end/63477 * gcc.dg/pr63477.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr63477.c Modified: trunk/gcc/testsuite/ChangeLog
Strangely, I cannot reproduce this warning anymore with GCC 8. Bisection points to r220157 (gcc 5.0.0) as the revision that fixed it. I've added the test case to the test suite in r254833 and with that I'm resolving this bug as fixed. Please reopen it if the problem reappears.
Hi, We get what seems like a spurious warning at the following location in LLVM: https://github.com/llvm/llvm-project/blob/master/llvm/lib/Target/AMDGPU/R600ISelLowering.cpp#L1718 The warning is: // warning: array subscript is above array bounds [-Warray-bounds] // if (NewBldVec[i] == NewBldVec[j]) { // ~~~~~~~~~~~^ This only occurs when compiling with GCC 7.1+ and 9.1/trunk (not with 8), with -O3 -Warray-bounds This has been creduce'd to: class a { int b; unsigned c; public: bool operator==(a) { return b && c; } }; class d { public: void e(); }; class f { a g(d &) const; }; a f::g(d &h) const { a j[1]; for (unsigned i;; i++) for (; i;) if (j[i] == j[0]) h.e(); } Could you please confirm the issue? Thank you!
(In reply to Alexandre Ganea from comment #4) The test case has been reduced a little too far -- it reads an uninitialized variable: for (unsigned i;; i++) for (; i;) if (j[i] == j[0]) h.e(); But the false positive can also be reproduced by initializing the variable to zero. Can you please open a new bug with the corrected test case?