https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671
--- Comment #46 from Bernd Edlinger <bernd.edlinger at hotmail dot de> --- (In reply to Jonathan Wakely from comment #45) > (In reply to rguent...@suse.de from comment #32) > > So you need to place may-alias at a point to make the following > > stmt safe: > > > > > c = *p; > > > > which means placing it on B, not only on the union (p is a B). > > > > Thus do > > > > struct B > > { > > int x; > > union U > > { > > int a; > > char b[sizeof (float)]; > > } u; > > int y; > > } __attribute__((may_alias)); > > In the real code there is no B, there is just the union, and it is assigned > directly, so it's more like: > > union function_buffer_members { > void* p; > void(*fp)(); > }; > > union function_buffer { > function_buffer_members members; > char data[sizeof(function_buffer_members)]; > }; > > struct function_base { > mutable function_buffer functor; > }; > > struct function : function_base { > void func(const function& f) { > this->functor = f.functor; > } > }; > > So it should only be necessary to put __attribute__((may_alias)) on union > function_buffer, right? That doesn't fix the problem though. Yes, it seems, the __attribute__((may_alias)) does not propagate from structure members to enclosing structure: If B has the may_alias, but it is a member of C then the test case fails again: 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__((may_alias)); struct C { struct B b; }; __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)) C * baz (C &x) { return &x; } __attribute__((noinline, noclone)) void foo (float x) { C b { 0, {}, 3 }, c; C *p = baz (b); new (b.b.u.b) A (x); c.b = p->b; bar (p->b, c.b); } int main () { foo (3.5f); }