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;

}

Reply via email to