In file included from /home/install/include/c++/12.0.1/algorithm:61, from repro.cpp:1: In function ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bar(int, int)::<lambda(int, int)> >]’, inlined from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = int*; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<bar(int, int)::<lambda(int, int)> >]’ at /home/install/include/c++/12.0.1/bits/stl_algo.h:1940:31, inlined from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = int*; _Compare = bar(int, int)::<lambda(int, int)>]’ at /home/install/include/c++/12.0.1/bits/stl_algo.h:4853:18, inlined from ‘int bar(int, int)’ at repro.cpp:17:14, inlined from ‘int foo(int)’ at repro.cpp:25:13: /home/install/include/c++/12.0.1/bits/stl_algo.h:1849:32: error: array subscript 16 is outside array bounds of ‘unsigned char [16]’ [-Werror=array-bounds] 1849 | std::__insertion_sort(__first, __first + int(_S_threshold), __comp); | ~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In function ‘int bar(int, int)’, inlined from ‘int foo(int)’ at repro.cpp:25:13: repro.cpp:4:7: note: at offset 64 into object ‘f.140’ of size 16 4 | int f[l]; | ^ cc1plus: all warnings being treated as errors make: *** [Makefile:5: all] Error 1 Getting the above bogus warning when compiling following reproducer #include <algorithm> static int bar(int n, int l) { // make function non-static and warning goes away int f[l]; int x = 0; int r = n; for (; x < l;) { if (r) { x = l; } else { // Take out this else and the warning goes away r = 1; } } if (r == 1) { // Take out this branch and the warning goes away std::sort(f, f + x, [](int a, int b) { return a > b; }); } return 1; } int foo(int n) { return bar(n, 4); } Compiled with HEAD of GCC (as of 20/01/2021) g++ -c -march=armv8-a -Werror -Wall -O2 repro.cpp The compiler sees that the size of the array is 4 ints (16-bytes), but doesn't see that x <= 4, so that no array out of bounds should occur. Workaround is to use malloc for the array.
The warning triggers for the out of bounds pointer addition in &f.148 + 64 for an array of 16 chars: int foo (int n) { unsigned char f.148[16]; ... <bb 8> [local count: 116203857]: _25 = ASSERT_EXPR <_15, _15 != &f.148>; _6 = (signed long) _14; _19 = _6 /[ex] 4; __n.3_20 = (long unsigned int) _19; _21 = __builtin_clzl (__n.3_20); _22 = 63 - _21; _23 = (long int) _22; _24 = _23 * 2; std::__introsort_loop<int*, long int, __gnu_cxx::__ops::_Iter_comp_iter<bar(int, int)::<lambda(int, int)> > > (&f.148, _25, _24, __comp); if (_14 > 64) goto <bb 9>; [50.00%] else goto <bb 15>; [50.00%] <bb 9> [local count: 58101929]: std::__insertion_sort.constprop (&f.148, &MEM <int[0:D.48109]> [(void *)&f.148 + 64B]); <<< -Warray-bounds goto <bb 14>; [100.00%] The basic block is removed later, in CCP3, as unreachable: Removing basic block 8 ;; basic block 8, loop depth 0 ;; pred: std::__insertion_sort.constprop (&f.148, &MEM <int[0:D.48109]> [(void *)&f.148 + 64B]); if (&MEM <int[0:D.48109]> [(void *)&f.148 + 64B] != _15) goto <bb 9>; [89.00%] else goto <bb 13>; [11.00%] ;; succ: 9 ;; 13 The warning runs too early to benefit from the subsequent simplification. This is one instance of a false positive that something like __builtin_warning() would cure. GCC 11 emits (and eliminates) the same invalid expression but the warning is suppressed because in GCC 11 -Warray-bounds wasn't issued code inlined from system headers. That's a GCC 12 change.
See also another similar test case reduced in https://bugzilla.redhat.com/show_bug.cgi?id=2051783: #include <algorithm> bool cond; int foo; int func (void) { int a[3], qa = 0; for(int i = 0; i < 3; i++) if (cond) a[qa++] = foo; std::sort (a, a + qa); return 0; } The warning is issued for the synthesized call to std::__insertion_sort.isra() in basic block 9 (vrp1 output): <bb 9> [local count: 71766220]: std::__insertion_sort.isra (&a, &MEM <int[3]> [(void *)&a + 64B]); <<< -Warray-bounds goto <bb 14>; [100.00%] The block is unreachable but GCC is unable to determine that from the loop. Adding an annotation just after the loop asserting that avoids the warning and also improves the emitted object code. The same warning triggers in GCC 11 with -Wsystem-headers. The difference in GCC 12 is that -Wsystem-headers no longer disables warnings for code defined in system headers that's inlined into user code.
GCC 12.1 is being released, retargeting bugs to GCC 12.2.
GCC 12.2 is being released, retargeting bugs to GCC 12.3.
This seems to be fixed on trunk - can somebody bisect what did so?
r13-2894-gbe4a6551ed37c1e7dbdfb9400fc2e2b5d40c5be2 made the warning go away.
The master branch has been updated by Richard Biener <rguenth@gcc.gnu.org>: https://gcc.gnu.org/g:790ff87f675f28bce5e7e35918ae09c3ece4ec4d commit r13-4499-g790ff87f675f28bce5e7e35918ae09c3ece4ec4d Author: Richard Biener <rguenther@suse.de> Date: Tue Dec 6 08:22:01 2022 +0100 tree-optimization/104165 - bougs -Warray-bounds, add testcase The following adds the testcase from the description which was fixed by r13-2894-gbe4a6551ed37c1. PR tree-optimization/104165 * g++.dg/warn/Warray-bounds-pr104165-1.C: New testcase.
I have opened PR107986 for the testcase in comment#2 which isn't yet fixed on trunk.
GCC 12.3 is being released, retargeting bugs to GCC 12.4.
This issue happens in GCC 13.2 as well: https://godbolt.org/z/TfGx3YccG
This just hit me on gcc 14.1: https://godbolt.org/z/31G5dxz55
(In reply to teodor_spaeren from comment #11) > This just hit me on gcc 14.1: > > https://godbolt.org/z/31G5dxz55 It's PR107986 and not this one. The underlying reason is different.
For anyone attempting to claim this not fixed for 13 or later please see PR107986 first.
GCC 12.4 is being released, retargeting bugs to GCC 12.5.