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

Jan Hubicka <hubicka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jason at redhat dot com

--- Comment #4 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
Is this valid C++? bar.mem is non-POD and is already constructed and it seems
fishy to placement new it to something different.
Devirtualization machinery does not consider that substructure of polymorphic
type may be replaced by arbitrary other type via placement new.

The testcase works on mainline. On GCC 7 we get:
  MEM[(struct foo *)&b].D.6234._vptr.base = &MEM[(void *)&_ZTV3fooIxE + 16B];   
  MEM[(struct foo *)&b].D.6370._vptr.base = &MEM[(void *)&_ZTV3fooIiE + 16B];   
  b.val = &b.mem;                                                               
  _8 = MEM[(struct base * *)&b + 8B];                                           
  _10 = _8->_vptr.base;                                                         
  _11 = *_10;                                                                   
  OBJ_TYPE_REF(_11;(struct base)_8->0) (_8);                                    
in a.C.036t.ealias and incorrect devirtualization happens in fre1 just after:
int main() ()
{
  struct bar b;

  <bb 2> [100.00%]:
  MEM[(struct foo *)&b].D.6234._vptr.base = &MEM[(void *)&_ZTV3fooIxE + 16B];
  MEM[(struct foo *)&b].D.6370._vptr.base = &MEM[(void *)&_ZTV3fooIiE + 16B];
  b.val = &b.mem;
  foo<long long int>::f (&b.mem);

}
because of:
  Targets of polymorphic call of type 0:struct base token 0                     
    Outer type:struct foo offset 0                                              
    This is a complete list.                                                    
       void foo<T>::f() [with T = long long int]/73                             

a.C:15:28: note: converting indirect call to function void foo<T>::f() [with T
= long long int]

On mainline we get in the same context:
   Type inheritance inconsistent devirtualization of OBJ_TYPE_REF(f;&b.mem->0)
(&b.mem);
 to OBJ_TYPE_REF(f;&b.mem->0)                                                   
  Removed EH side-effects.                                                      

So the devirt machinery is says wrong answer, but FRE got smarter and
determines the correct destination with priority.

Reply via email to