Created attachment 51467 [details] example test file There is no warning for array bounds overrun with this code. Compiled with Gcc-11.2.0 gcc -o test string_array_concat.c -W -Wall -Wextra -Warray-bounds=2 -O2 Gives other warning from printf usage only In file included from /usr/include/stdio.h:867, from string_array_concat.c:1: In function ‘printf’, inlined from ‘main’ at string_array_concat.c:13:3: /usr/include/x86_64-linux-gnu/bits/stdio2.h:107:10: warning: ‘%s’ directive argument is null [-Wformat-overflow=] 107 | return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ()); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Though eg CLANG does give warning for this: fredrik@deadbolt ~/test$ clang -o test string_array_concat.c string_array_concat.c:13:30: warning: array index 1 is past the end of the array (which contains 1 element) [-Warray-bounds] printf("item_at_1 = %s\n", item[1]); ^ ~ string_array_concat.c:3:1: note: array 'item' declared here static const char *item[1] = { "TestString" }; ^ string_array_concat.c:15:10: warning: array index 1 is past the end of the array (which contains 1 element) [-Warray-bounds] return item[1]; ^ ~ string_array_concat.c:3:1: note: array 'item' declared here static const char *item[1] = { "TestString" }; ^ 2 warnings generated.
The root cause of the missing warning is the same as that of some of the same false negatives discussed in pr35587 and pr86691: GCC folds accesses to elements of constant arrays with initializers very early on. Accesses to elements for which no initializer has been explicitly provided (and those that are implicitly zero) are folded to zero. The folding is done without regard to the index and even without optimization. At the time the warning runs the accesses are gone from the IL. The simple test case below shows this effect: $ cat z.c && gcc -O2 -S -Wall -fdump-tree-original=/dev/stdout -fdump-tree-gimple=/dev/stdout z.c const int a[1] = { 1 }; int f (void) { return a[1]; } ;; Function f (null) ;; enabled by -tree-original { return (int) a[1]; } int f () { int D.1982; D.1982 = 0; return D.1982; } *** This bug has been marked as a duplicate of bug 35587 ***