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.