https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95635
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Depends on| |86318 Component|c |tree-optimization Summary|-Warray-bounds falsely |-Warray-bounds while |claims out-of-bounds access |iterating over an escaped | |constant local array Keywords| |diagnostic, | |missed-optimization Blocks| |56456 --- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> --- -Warray-bounds relies on the optimizer to eliminate dead code. In the test case, GCC (unnecessarily) assumes that the escaped array may be modified by the call to c(). This missing optimization (tracked in pr86318) keeps the second test from being eliminated (see also the test case below). I note that Clang optimizes the function to a no-op as expected. That aside, arrays with zero elements are meant to be used as trailing members of structures. Using them anywhere else is a bug waiting to happen. I would recommend against using them in any other contexts as they may start getting diagnosed even more aggressively (e.g., even declaring one that's not last in a struct might trigger a warning in the future). I'll keep this open since a similar warning can be triggered with a non-empty array due to the same limitation. A test case for the missing optimization: $ cat pr95635.c && gcc -O3 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout pr95635.c void f (const int*); void g (void) { const int i = -1; f (&i); if (i != -1) // folded to false __builtin_abort (); // eliminated } void h (void) { const int a[] = { -1 }; f (a); if (*a != -1) // not folded __builtin_abort (); } ;; Function g (g, funcdef_no=0, decl_uid=1933, cgraph_uid=1, symbol_order=0) g () { const int i; <bb 2> [local count: 1073741824]: i = -1; f (&i); i ={v} {CLOBBER}; return; } ;; Function h (h, funcdef_no=1, decl_uid=1937, cgraph_uid=2, symbol_order=1) h () { const int a[1]; int _1; <bb 2> [local count: 1073741824]: a[0] = -1; f (&a); _1 = a[0]; if (_1 != -1) goto <bb 3>; [0.00%] else goto <bb 4>; [100.00%] <bb 3> [count: 0]: __builtin_abort (); <bb 4> [local count: 1073741824]: a ={v} {CLOBBER}; return; } Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56456 [Bug 56456] [meta-bug] bogus/missing -Warray-bounds https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86318 [Bug 86318] const local aggregates can be assumed not to be modified even when escaped