Skip to content

CWG2658 [expr.const] P1331R2 broke trivial union copying in core constant expressions #189

@hubert-reinterpretcast

Description

@hubert-reinterpretcast

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions