Can one change active member in a union with copying of previous active member's value using std::construct_at?
This minimal example
#include <memory>
constexpr int f() {
union U {
char x{0};
int y;
} u;
std::construct_at(&u.y, u.x);
return u.y;
}
static_assert( f() == 0 );
is accepted by GCC and MSVC, but Clang rejects it with the error:
/opt/compiler-explorer/clang-19.1.0/bin/../include/c++/v1/__memory/construct_at.h:41:50:
note: read of member 'x' of union with active member 'y' is not allowed in a constant expression
41 | return ::new (std::__voidify(*__location)) _Tp(std::forward<_Args>(__args)...);
Online demo: https://gcc.godbolt.org/z/xrj57jroj
Which implementation is correct here?