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

--- Comment #3 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
OK, C++ FE can't do that because virtual call is wrapper by foo_virtual_inner.
After inlining we see:
Determining dynamic type for call: OBJ_TYPE_REF(_5;(struct A)p_2(D)->0)
(p_2(D), p_2(D));
  Starting walk at: _4 = MEM[(struct A *)p_2(D)]._vptr.A;
  instance pointer: p_2(D)  Outer instance pointer: p_2(D) offset: 0 (bits)
vtbl reference: MEM[(struct A *)p_2(D)]._vptr.A
  No dynamic type change found.
  Targets of polymorphic call of type 0:struct A token 0
    Outer type (dynamic):struct A (or a derived type) offset 0 Speculative
outer type:struct Aint (or a derived type) at offset 0
    This is partial list; extra targets may be defined in other units. (derived
types included) (speculative derived types included)
       virtual A& Aint::operator+=(const A&)/3

foo_virtual (struct Aint * p)
{
  int (*) () * _4;
  int (*) () _5;

  <bb 2> :
  _4 = MEM[(struct A *)p_2(D)]._vptr.A;
  _5 = *_4;
  OBJ_TYPE_REF(_5;(struct A)p_2(D)->0) (p_2(D), p_2(D));
  return;

}

The reason why we do not devirtualize is that only information about Aint is
the type of function parameter and we do not believe it implies the type of
memory location it points to because there is no read or anything from that
pointer before it is casted to struct A* and pointer of a given type does not
need to necessarily point to memory location of the same type unless you
dereference it.

Is it really valid to devirtualize here?

Reply via email to