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.

Reply via email to