It seems the structure aliasing patch exposed what appears to be a bug in the C FE.
Our docs on transparent union say "@item transparent_union This attribute, attached to a function parameter which is a union, means that the corresponding argument may have the type of any union member, but the argument is passed as if its type were that of the first union member. For more details see @xref{Type Attributes}. You can also use this attribute on a @code{typedef} for a union data type; then it applies to all function parameters with that type. " However, given the following code: struct s1 { int x; }; struct s2 { int x; }; union u1 { struct s1 *xs1; struct s2 *xs2; } __attribute__ ((__transparent_union__)); extern void g(union u1 p); void f() { struct s1 addr; g( (struct s2 *)&addr ); } We generate: f () { union u1 addr.0D.1248; union u1 addr.1D.1249; struct s1 addrD.1247; addr.1D.1249 = (union u1) &addrD.1247; addr.0D.1248 = addr.1D.1249; g (addr.0D.1248); } Note clearly that we are casting &addr (a pointer) to a union type (an aggregate). It's also not what the user actually wrote, nor what the docs say (the docs imply it would be as if it was casted to a struct s1 *, the first member of the union). This confuses the structure aliasing code, because it doesn't expect to see an addressof operation casted to an aggregate. Is this really supposed to look like this?