[clang] [clang] Implement CWG3135 - constexpr structured bindings with prvalues from tuples (PR #191880)
Matthias Wippich via cfe-commits
cfe-commits at lists.llvm.org
Tue May 5 13:53:49 PDT 2026
================
@@ -1380,47 +1380,52 @@ static bool checkTupleLikeDecomposition(Sema &S,
return true;
Expr *Init = E.get();
- // Given the type T designated by std::tuple_element<i - 1, E>::type,
+ // Given the type T designated by std::tuple_element<i - 1, E>::type
QualType T = getTupleLikeElementType(S, Loc, I, DecompType);
if (T.isNull())
return true;
- // each vi is a variable of type "reference to T" initialized with the
- // initializer, where the reference is an lvalue reference if the
- // initializer is an lvalue and an rvalue reference otherwise
- QualType RefType =
- S.BuildReferenceType(T, E.get()->isLValue(), Loc, B->getDeclName());
- if (RefType.isNull())
+ // C++26 [dcl.struct.bind]p7:
+ // and the type Ui, defined as Ti if the initializer is a prvalue,
+ // as "lvalue reference to Ti" if the initializer is an lvalue,
+ // or as "rvalue reference to Ti" otherwise
+ // "defined as Ti if the initializer is a prvalue" was introduced by CWG3135
+ QualType U = E.get()->isPRValue()
+ ? T
+ : S.BuildReferenceType(T, E.get()->isLValue(), Loc,
+ B->getDeclName());
+ if (U.isNull())
return true;
// Don't give this VarDecl a TypeSourceInfo, since this is a synthesized
// entity and this type was never written in source code.
- auto *RefVD =
+ auto *BindingVD =
VarDecl::Create(S.Context, Src->getDeclContext(), Loc, Loc,
- B->getDeclName().getAsIdentifierInfo(), RefType,
+ B->getDeclName().getAsIdentifierInfo(), U,
/*TInfo=*/nullptr, Src->getStorageClass());
- RefVD->setLexicalDeclContext(Src->getLexicalDeclContext());
- RefVD->setTSCSpec(Src->getTSCSpec());
- RefVD->setImplicit();
+ BindingVD->setLexicalDeclContext(Src->getLexicalDeclContext());
+ BindingVD->setTSCSpec(Src->getTSCSpec());
+ BindingVD->setImplicit();
if (Src->isInlineSpecified())
- RefVD->setInlineSpecified();
- RefVD->getLexicalDeclContext()->addHiddenDecl(RefVD);
+ BindingVD->setInlineSpecified();
+ BindingVD->getLexicalDeclContext()->addHiddenDecl(BindingVD);
- InitializedEntity Entity = InitializedEntity::InitializeBinding(RefVD);
- InitializationKind Kind = InitializationKind::CreateCopy(Loc, Loc);
+ InitializedEntity Entity = InitializedEntity::InitializeBinding(BindingVD);
+ InitializationKind Kind =
+ E.get()->isPRValue() ? InitializationKind::CreateDirect(Loc, Loc, Loc)
----------------
Tsche wrote:
I was seeing assertion failures and utterly broken diagnostics with copy initialization in the PR value case. This seemed like the least intrusive fix that still results in semantically correct behavior.
https://github.com/llvm/llvm-project/pull/191880
More information about the cfe-commits
mailing list