https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100004
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |rguenth at gcc dot gnu.org Version|unknown |11.0 Keywords| |missed-optimization Status|UNCONFIRMED |RESOLVED Resolution|--- |WONTFIX --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- void assign_via_pointer(Wrap1* w1, Wrap2* w2) { Foo* f1 = &w1->foo; Foo* f2 = &w2->foo; f1->x = 5; f1->x = f2->x; to GCC &wN->foo is just address arithmetic - GCC does not assume that at w1 or w2 dynamic types of type Wrap1 or Wrap2 reside and thus it cannot disambiguate f1->x and f2->x here because the actual accesses only involve the type Foo. In the assign_direct case the access paths contain Wrap1 and Wrap2 and thus we _do_ assume dynamic types Wrap1 and Wrap2 are in effect and thus we can disambiguate. This is how GIMPLEs memory model works, there's no bug here. Maybe the C++ language makes more strict guarantees (but I think it would run against standard coding practices).