[clang] [clang] Implement CWG3135 - constexpr structured bindings with prvalues from tuples (PR #191880)
Yanzuo Liu via cfe-commits
cfe-commits at lists.llvm.org
Wed May 6 04:50: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)
----------------
zwuis wrote:
They are semantically different. Copy initialization ignores member functions with `explicit`.
Please fix assertion failures or leave a FIXME comment.
https://github.com/llvm/llvm-project/pull/191880
More information about the cfe-commits
mailing list