-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Full name of submitter (unless configured in github; will be published with the issue): Hubert Tong
Reference (section label): expr.const
Link to reflector thread (if any): N/A
Issue description:
Consider:
struct A {
char c; int x;
constexpr A() : c(1), x(2) {}
};
union U { A a; };
constexpr int f() {
U u = { A() };
U v = u; // indeterminate padding bytes read!
return u.a.x;
}
extern constexpr int x = f();
https://eel.is/c++draft/expr.const#5.11 added by P1331R2 prohibits lvalue-to-rvalue conversion of objects having indeterminate value during evaluation of a core constant expression. Trivial copy constructors of unions copy the object representation (not just the active member). The new prohibition causes cases where bytes not involved in the value presentation of the active member and having indeterminate values would prevent a union from being copied by a trivial copy constructor (for example, the padding bytes in the above case).
Note: The source of a union copy is never a prvalue within the evaluation of a trivial copy constructor because the reference parameter is bound to a glvalue.
Suggested resolution:
Add a new paragraph after paragraph 6:
For the purposes of determining whether an expression E is a core constant expression, the evaluation of a call to a member function of std::allocator<T>
, [ ... ]
For the purposes of determining whether E is a core constant expression, lvalue-to-rvalue conversion of an object of indeterminate value during the evaluation of a call to a trivial copy/move constructor or copy/move assignment operator of a union does not disqualify E from being a core constant expression unless if the active member of the source union object contains a subobject of indeterminate value.