https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |redi at gcc dot gnu.org --- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> --- I believe this all boils down to: inline void* operator new(__SIZE_TYPE__, void *p) { return p; } struct A { A (float x) : f (x) {} float f; }; struct B { int x; union U { int a; char b[sizeof (float)]; } u; int y; }; __attribute__((noinline, noclone)) void bar (B &x, B &y) { if (x.x != 0 || x.y != 3 || y.x != 0 || y.y != 3) __builtin_abort (); float f; __builtin_memcpy (&f, x.u.b, sizeof (float)); if (f != 3.5f) __builtin_abort (); __builtin_memcpy (&f, y.u.b, sizeof (float)); if (f != 3.5f) __builtin_abort (); } __attribute__((noinline, noclone)) B * baz (B &x) { return &x; } __attribute__((noinline, noclone)) void foo (float x) { B b { 0, {}, 3 }, c; B *p = baz (b); new (b.u.b) A (x); c = *p; bar (*p, c); } int main () { foo (3.5f); } which fails also on x86_64-linux at -O2. And that testcase regressed with r223126. Now whether this is valid C++, no idea, placement new is messy.