Open hubert-reinterpretcast opened 1 year ago
@llvm/issue-subscribers-c-20
I don't think any lvalue-to-rvalue conversion happens in a defaulted copy constructor for a union. Per [class.copy.ctor]/15:
The implicitly-defined copy/move constructor for a union X copies the object representation ([basic.types.general]) of X. For each object nested within ([intro.object]) the object that is the source of the copy, a corresponding object o nested within the destination is identified (if the object is a subobject) or created (otherwise), and the lifetime of o begins before the copy is performed.
I wouldn't interpret "copies the object representation" as performing an lvalue-to-rvalue conversion. If you do, then you also can't copy a union
that's fully initialized but has padding, because the object representation can contain indeterminate values in that case too.
I wouldn't interpret "copies the object representation" as performing an lvalue-to-rvalue conversion. If you do, then you also can't copy a
union
that's fully initialized but has padding, because the object representation can contain indeterminate values in that case too.
That's CWG 2658. The wording was new from a paper that is now the subject of multiple Core Issues.
Lvalue-to-rvalue conversion of objects having indeterminate value is not allowed during evaluation of a core constant expression (see N4919 subclause 7.7 [expr.const] bullet 5.11). Clang allows such lvalue-to-rvalue conversion during the constant evaluation of trivial union copy constructors.
In the case below, the
y
member ofu
has indeterminate value (as does the corresponding bytes of the object representation) when the initialization ofv
is performed. ICC correctly diagnoses the issue.Compiler Explorer link: https://godbolt.org/z/6174nqhbE
SOURCE (
<stdin>
):COMPILER INVOCATION:
ACTUAL OUTPUT:
(Clean compile)
EXPECTED OUTPUT:
(Error that
x
is not initialized by a constant expression)COMPILER VERSION INFO (
clang++ -v
):