https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99635
Bug ID: 99635 Summary: -Warray-bounds where -Wzero-length-bounds is expected Product: gcc Version: 11.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: --- The store to p->da[1] is out of bounds and diagnosed as expected. The store to p->da[0], however, is in bounds but overlaps with p->b0i and so should be diagnosed by -Wzero-length-bounds. $ cat t.C && gcc -O2 -S -fdump-tree-vrp1=/dev/stdout -Wall t.C inline void* operator new (__SIZE_TYPE__, void *p) { return p; } struct B0 { int b0i; }; struct B1: virtual B0 { }; struct B2: virtual B0 { }; struct D: B1, B2 { int di, da[0]; }; void* f () { D *p = (D*)new char[sizeof (D) + 2 * sizeof (D::da[0])]; p->da[0] = (char*)p->da - (char*)p; // -Wzero-length-bounds expected D d; p->da[1] = (char*)&d.b0i - (char*)&d; // -Warray-bounds (good) return p; } ;; Function f (_Z1fv, funcdef_no=1, decl_uid=2404, cgraph_uid=11, symbol_order=10) ;; 1 loops found ;; ;; Loop 0 ;; header 0, latch 1 ;; depth 0, outer -1 ;; nodes: 0 1 2 ;; 2 succs { 1 } SSA replacement table N_i -> { O_1 ... O_j } means that N_i replaces O_1, ..., O_j _6 -> { _3 } Incremental SSA update started at block: 2 Number of blocks in CFG: 3 Number of blocks to update: 1 ( 33%) Value ranges after VRP: _3: void * [1B, +INF] _6: struct D * [1B, +INF] EQUIVALENCES: { _3 } (1 elements) t.C: In function ‘void* f()’: t.C:11:10: warning: array subscript 0 is outside array bounds of ‘int [0]’ [-Warray-bounds] 11 | p->da[0] = (char*)p->da - (char*)p; // -Wzero-length-bounds expected | ~~~~~~~^ t.C:6:28: note: while referencing ‘D::da’ 6 | struct D: B1, B2 { int di, da[0]; }; | ^~ t.C:14:10: warning: array subscript 1 is outside array bounds of ‘int [0]’ [-Warray-bounds] 14 | p->da[1] = (char*)&d.b0i - (char*)&d; // -Warray-bounds (good) | ~~~~~~~^ t.C:6:28: note: while referencing ‘D::da’ 6 | struct D: B1, B2 { int di, da[0]; }; | ^~ void * f () { struct D * _3; <bb 2> [local count: 1073741824]: _3 = operator new [] (32); _3->da[0] = 20; _3->da[1] = 20; return _3; }