https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92765
--- Comment #18 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Also, note that union doesn't have to be visible on the access path, e.g. union U { struct S { char a[2]; char b[2]; char c[2]; } s; struct T { char d[6]; } t; } u; __attribute__((noipa)) void bar (char *p) { if (__builtin_strcmp (p, "a") != 0) __builtin_abort (); __builtin_strcpy (u.t.d, "abcde"); } __attribute__((noipa)) void foo (void *x) { struct S *s = (struct S *) x; char *p = (char *) &s->b; bar (p); struct T *t = (struct T *) x; if (__builtin_strcmp (&t->d[2], "cde")) __builtin_abort (); } int main () { __builtin_strcpy (u.s.b, "a"); foo (&u); return 0; } is miscompiled too, there is no type punning through union, only active union member is ever read...