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; }