https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117679
Bug ID: 117679
Summary: Changing active member in a union with overlapping
copying not detected in constant expression
Product: gcc
Version: 14.2.1
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: fchelnokov at gmail dot com
Target Milestone: ---
In this program
```
struct A {
char u, v, w;
};
struct X { char x; };
struct B : X, A {
using A::operator=;
};
constexpr A f() {
union U {
A a{ 1, 2, 3 };
B b;
} u;
u.b = u.a;
return u.b;
}
// ok in GCC and MSVC, fails in Clang
static_assert( f().w == 3 );
int main() {
return f().w; //2 in GCC with -O0
}
```
constant evaluation of `f().w == 3` succeeds in GCC, but in runtime with -O0
switch `f().w` is evaluated as 2.
Clang here finds that `u.b = u.a;` is not a constant expression because it
simultaneously accesses two members of a union during copying. Online demo:
https://gcc.godbolt.org/z/Ks7oaoaz9
Related discussion: https://stackoverflow.com/q/79196052/7325599