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

Reply via email to