https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93582

--- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> ---
Below is a simplified C test case.  The warning is justified and works
correctly, but the index and the type it prints might be a little confusing.

The index corresponds to the MEM_REF offset which is set to zero by the front
end regardless of the value of the original offset (for an empty object). 
There's nothing the warning can do about that.  Rather than letting the
out-of-bounds reference result in a bogus value VRP could fold it to zero (that
would be consistent with what the folder does for accesses to constants), but
that seems like a separate issue.

For simplicity, the warning treats singleton objects the same as arrays of one
element, so the type ‘struct E[1]’ simply refers to the type of the global e. 
Since the warning also prints a note pointing to the object I wouldn't expect
this to be too big of a problem.

So unless this report is about the details of the message as opposed to issuing
it at all I'm inclined to resolve it as invalid.

$ cat t.c && gcc -O2 -S -Wall -fdump-tree-vrp=/dev/stdout t.c
struct E { } e;

struct A { int i; };

int f (void)
{
  struct E *ep = &e;
  return ((struct A*) (ep + 9))->i;
}

;; Function f (f, funcdef_no=0, decl_uid=1934, cgraph_uid=1, symbol_order=1)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2
;; 2 succs { 1 }

Value ranges after VRP:

_2: int VARYING


t.c: In function ‘f’:
t.c:8:32: warning: array subscript 0 is outside array bounds of ‘struct E[1]’
[-Warray-bounds]
    8 |   return ((struct A*) (ep + 1))->i;
      |                                ^~
t.C:1:14: note: while referencing ‘e’
    1 | struct E { } e;
      |              ^
f ()
{
  int _2;

  <bb 2> [local count: 1073741824]:
  _2 = MEM[(struct A *)&e].i;
  return _2;

}



;; Function f (f, funcdef_no=0, decl_uid=1934, cgraph_uid=1, symbol_order=1)

;; 1 loops found
;;
;; Loop 0
;;  header 0, latch 1
;;  depth 0, outer -1
;;  nodes: 0 1 2
;; 2 succs { 1 }

Value ranges after VRP:

_2: int VARYING


f ()
{
  int _2;

  <bb 2> [local count: 1073741824]:
  _2 = MEM[(struct A *)&e].i;
  return _2;

}

Reply via email to