https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78551
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jason at gcc dot gnu.org --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- Actually, no array is needed, struct A { union { short s; char d[2]; }; constexpr A (char x) : s(0x2020) { d[0] = x; } }; A c { 'a' }; ICEs as well. The C++ FE creates a CONSTRUCTOR that contains both initializer for s as well for d[0], that obviously can't be emitted properly. Before Nathan's fix, GCC just emitted garbage: .type c, @object .size c, 2 c: .value 8224 .byte 97 .zero 1 i.e. c actually didn't have size 2, but 4. struct A { union { short s; char d[2]; }; constexpr A (const char x) : s(0x2020) { d[0] = x; } }; constexpr A c { 'a' }; const A *p = &c; is rejected by clang++, because of: assignment to member 'd' of union with active member 's' is not allowed in a constant expression g++ still ICEs. Finally: struct A { union { short s; char d[2]; }; constexpr A (const char x) : d{0,0} { d[0] = x; d[1] = x; } }; constexpr A c { 'a' }; const A *p = &c; is accepted by both compilers and looks good.