https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82588
Bug ID: 82588 Summary: missing -Warray-bounds on a excessively large index Product: gcc Version: 8.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- GCC fails to issue a -Warray-bounds warning for indices so large that they cannot be valid even for the largest objects. In function f0() below, GCC recognizes that the signed distance between the beginning of the array and the end pointer cannot be positive and transforms the function into an unconditional call to abort, but it doesn't issue any sort of a diagnostic. -Warray-bounds would seem to be appropriate here. Likewise in function f1(). Similarly in function f2(), the size of the member array cannot be half the address space because it would leave no room for the remaining members of the same struct. So again, -Warray-bounds could be issued for this pathological case. The comment in check_array_ref that reads "Can not check flexible arrays." indicates the absence of checking for flexible array members is intentional, but it can be tightened up to detect these boundary conditions. $ cat a.c && gcc -O2 -S -Wall -Warray-bounds -fdump-tree-optimized=/dev/stdout a.c struct A { int n; char a[]; }; void f0 (void) { extern int a[]; int *e = a + __SIZE_MAX__ / sizeof (int) + 1; // missing warning if (e - a <= 0) __builtin_abort (); } int f1 (void) { extern int a[]; return a[__SIZE_MAX__ / sizeof (int) + 1]; // missing -Warray-bounds } int f2 (struct A *a) { return a->a[__SIZE_MAX__ / 2]; // missing -Warray-bounds } ;; Function f0 (f0, funcdef_no=0, decl_uid=1834, cgraph_uid=0, symbol_order=0) (unlikely executed) f0 () { <bb 2> [100.00%] [count: 0]: __builtin_abort (); } ;; Function f1 (f1, funcdef_no=1, decl_uid=1840, cgraph_uid=1, symbol_order=1) f1 () { int _2; <bb 2> [100.00%] [count: INV]: _2 = a[4611686018427387904]; return _2; } ;; Function f2 (f2, funcdef_no=2, decl_uid=1845, cgraph_uid=2, symbol_order=2) f2 (struct A * a) { char _1; int _4; <bb 2> [100.00%] [count: INV]: _1 = a_3(D)->a[9223372036854775807]; _4 = (int) _1; return _4; }