llvm / llvm/llvm-project

Modifying inactive union member in constant expression not rejected when implicit lifetime start is disallowed

Open
#211,309 1 comment 0 reactions 0 assignees View on GitHub
clang:frontend constexpr
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

This code is the constexpr version of [Example 2 from [class.union]/5](https://eel.is/c++draft/class.union#general-example-2)

```cpp
struct X { const int a; int b; };
union Y {
X x;
int k;
constexpr Y() : x{1, 2} {}
};

constexpr int test() {
Y y;
y.k = 4; // change active member to 'k'
y.x.b = 0; // undefined behavior: y.x.b modified outside its lifetime,
// S(y.x.b) is empty because X's default constructor is deleted,
// so union member y.x's lifetime does not implicitly start
return y.x.b;
}

int main() {
constexpr int val = test(); // force constant evaluation
return val;
}
```

GCC correctly rejects this due to undefined behavior in constant evaluation, while Clang doesn't. [godbolt](https://godbolt.org/z/c47TGK6G4)

Contributor guide

Open the contributing guide

Research direction

Start by compiling the reduced C++ example with Clang and GCC and compare their constant-evaluation behavior. Trace Clang's handling of the inactive union member assignment during constant evaluation; done means Clang rejects the constexpr declaration for undefined behavior, matching GCC.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.