https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101436
Martin Sebor <msebor at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- See Also|https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=98266, | |https://gcc.gnu.org/bugzill | |a/show_bug.cgi?id=101374 | Resolution|--- |WONTFIX Status|UNCONFIRMED |RESOLVED --- Comment #2 from Martin Sebor <msebor at gcc dot gnu.org> --- The reports in pr98266 and pr101374 are unrelated. This instance of the warning is by design: it points out an access to an object of one type (B<C2>) by an lvalue of an unrelated type (B<C1>). Such accesses are invalid and can be unsafe regardless of whether the offset of the accessed member is fully within the bounds of the accessed object (GCC relies on the requirement to optimize code). The problem can be reduced to the following C example: $ cat a.c && gcc -Wall -S -O2 a.c struct A { int i; }; struct B { struct A a; int j, k; }; struct C { struct A a; int j; }; int is_B (struct A *); // return nonzero for instances of B int f (struct C c) { struct A *p = &c.a; if (is_B (p)) { struct B *q = (struct B*)p; return q->a.i; // invalid } return 0; } a.c: In function ‘f’: a.c:13:15: warning: array subscript ‘struct B[0]’ is partly outside array bounds of ‘struct C[1]’ [-Warray-bounds] 13 | return q->a.i; | ^~ a.c:7:17: note: object ‘c’ of size 8 7 | int f (struct C c) | ~~~~~~~~~^ The cast that safely converts a pointer/reference down an inheritance hierarchy is dynamic_cast. Using it avoids the warning. Using typeid and static_cast is a convoluted way to do the same thing except that it exposes the potential problem to the warning code: a) because the typeid equality isn't folded and b) the static_cast is just a straight conversion whereas dynamic_cast is a function call whose result in the IL is unrelated to its operand.