https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/81095
Testing libc++'s CI. >From 906fbf5b0796a85bf54028dfaa8e6343ea441a51 Mon Sep 17 00:00:00 2001 From: Younan Zhang <zyn7...@gmail.com> Date: Thu, 8 Feb 2024 15:07:47 +0800 Subject: [PATCH] GH70601 --- clang/include/clang/Sema/Sema.h | 15 ++-- clang/lib/Sema/SemaTemplate.cpp | 83 ++++++++++--------- clang/lib/Sema/SemaTemplateInstantiate.cpp | 21 +++-- .../lib/Sema/SemaTemplateInstantiateDecl.cpp | 12 ++- clang/test/SemaTemplate/concepts-lambda.cpp | 19 +++++ 5 files changed, 92 insertions(+), 58 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 3c26003b5bda7..afc74f1a64551 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -8343,12 +8343,14 @@ class Sema final { ConceptDecl *NamedConcept, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, - SourceLocation EllipsisLoc); + SourceLocation EllipsisLoc, + bool EvaluateConstraint = true); bool AttachTypeConstraint(AutoTypeLoc TL, NonTypeTemplateParmDecl *NewConstrainedParm, NonTypeTemplateParmDecl *OrigConstrainedParm, - SourceLocation EllipsisLoc); + SourceLocation EllipsisLoc, + bool EvaluateConstraint = true); bool RequireStructuralType(QualType T, SourceLocation Loc); @@ -8479,11 +8481,11 @@ class Sema final { const TemplateArgumentListInfo *TemplateArgs); ExprResult - CheckConceptTemplateId(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, + CheckConceptTemplateId(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const TemplateArgumentListInfo *TemplateArgs); + const TemplateArgumentListInfo *TemplateArgs, + bool EvaluateConstraint = true); void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc); @@ -10518,7 +10520,8 @@ class Sema final { bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC, const MultiLevelTemplateArgumentList &TemplateArgs, - bool EvaluateConstraint); + bool RebuildConstraint, + bool EvaluateConstraints = true); bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index cf781e0e1bf3f..9c7a936aac1d6 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1176,13 +1176,13 @@ bool Sema::BuildTypeConstraint(const CXXScopeSpec &SS, ConstrainedParameter, EllipsisLoc); } -template<typename ArgumentLocAppender> +template <typename ArgumentLocAppender> static ExprResult formImmediatelyDeclaredConstraint( Sema &S, NestedNameSpecifierLoc NS, DeclarationNameInfo NameInfo, ConceptDecl *NamedConcept, SourceLocation LAngleLoc, SourceLocation RAngleLoc, QualType ConstrainedType, SourceLocation ParamNameLoc, ArgumentLocAppender Appender, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, bool EvaluateConstraint) { TemplateArgumentListInfo ConstraintArgs; ConstraintArgs.addArgument( @@ -1233,7 +1233,8 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS, ConceptDecl *NamedConcept, const TemplateArgumentListInfo *TemplateArgs, TemplateTypeParmDecl *ConstrainedParameter, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, + bool EvaluateConstraint) { // C++2a [temp.param]p4: // [...] If Q is of the form C<A1, ..., An>, then let E' be // C<T, A1, ..., An>. Otherwise, let E' be C<T>. [...] @@ -1243,17 +1244,17 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS, QualType ParamAsArgument(ConstrainedParameter->getTypeForDecl(), 0); - ExprResult ImmediatelyDeclaredConstraint = - formImmediatelyDeclaredConstraint( - *this, NS, NameInfo, NamedConcept, - TemplateArgs ? TemplateArgs->getLAngleLoc() : SourceLocation(), - TemplateArgs ? TemplateArgs->getRAngleLoc() : SourceLocation(), - ParamAsArgument, ConstrainedParameter->getLocation(), - [&] (TemplateArgumentListInfo &ConstraintArgs) { - if (TemplateArgs) - for (const auto &ArgLoc : TemplateArgs->arguments()) - ConstraintArgs.addArgument(ArgLoc); - }, EllipsisLoc); + ExprResult ImmediatelyDeclaredConstraint = formImmediatelyDeclaredConstraint( + *this, NS, NameInfo, NamedConcept, + TemplateArgs ? TemplateArgs->getLAngleLoc() : SourceLocation(), + TemplateArgs ? TemplateArgs->getRAngleLoc() : SourceLocation(), + ParamAsArgument, ConstrainedParameter->getLocation(), + [&](TemplateArgumentListInfo &ConstraintArgs) { + if (TemplateArgs) + for (const auto &ArgLoc : TemplateArgs->arguments()) + ConstraintArgs.addArgument(ArgLoc); + }, + EllipsisLoc, EvaluateConstraint); if (ImmediatelyDeclaredConstraint.isInvalid()) return true; @@ -1271,7 +1272,8 @@ bool Sema::AttachTypeConstraint(NestedNameSpecifierLoc NS, bool Sema::AttachTypeConstraint(AutoTypeLoc TL, NonTypeTemplateParmDecl *NewConstrainedParm, NonTypeTemplateParmDecl *OrigConstrainedParm, - SourceLocation EllipsisLoc) { + SourceLocation EllipsisLoc, + bool EvaluateConstraint) { if (NewConstrainedParm->getType() != TL.getType() || TL.getAutoKeyword() != AutoTypeKeyword::Auto) { Diag(NewConstrainedParm->getTypeSourceInfo()->getTypeLoc().getBeginLoc(), @@ -1296,7 +1298,7 @@ bool Sema::AttachTypeConstraint(AutoTypeLoc TL, for (unsigned I = 0, C = TL.getNumArgs(); I != C; ++I) ConstraintArgs.addArgument(TL.getArgLoc(I)); }, - EllipsisLoc); + EllipsisLoc, EvaluateConstraint); if (ImmediatelyDeclaredConstraint.isInvalid() || !ImmediatelyDeclaredConstraint.isUsable()) return true; @@ -4990,13 +4992,11 @@ void Sema::diagnoseMissingTemplateArguments(TemplateName Name, } } -ExprResult -Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &ConceptNameInfo, - NamedDecl *FoundDecl, - ConceptDecl *NamedConcept, - const TemplateArgumentListInfo *TemplateArgs) { +ExprResult Sema::CheckConceptTemplateId( + const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, + const DeclarationNameInfo &ConceptNameInfo, NamedDecl *FoundDecl, + ConceptDecl *NamedConcept, const TemplateArgumentListInfo *TemplateArgs, + bool EvaluateConstraint) { assert(NamedConcept && "A concept template id without a template?"); llvm::SmallVector<TemplateArgument, 4> SugaredConverted, CanonicalConverted; @@ -5011,30 +5011,33 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS, Context, NamedConcept->getDeclContext(), NamedConcept->getLocation(), CanonicalConverted); ConstraintSatisfaction Satisfaction; - bool AreArgsDependent = - TemplateSpecializationType::anyDependentTemplateArguments( + bool ShouldEvaluate = + EvaluateConstraint && + !TemplateSpecializationType::anyDependentTemplateArguments( *TemplateArgs, CanonicalConverted); - MultiLevelTemplateArgumentList MLTAL(NamedConcept, CanonicalConverted, - /*Final=*/false); - LocalInstantiationScope Scope(*this); - - EnterExpressionEvaluationContext EECtx{ - *this, ExpressionEvaluationContext::ConstantEvaluated, CSD}; - - if (!AreArgsDependent && - CheckConstraintSatisfaction( - NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL, - SourceRange(SS.isSet() ? SS.getBeginLoc() : ConceptNameInfo.getLoc(), - TemplateArgs->getRAngleLoc()), - Satisfaction)) - return ExprError(); + if (ShouldEvaluate) { + MultiLevelTemplateArgumentList MLTAL(NamedConcept, CanonicalConverted, + /*Final=*/false); + LocalInstantiationScope Scope(*this); + + EnterExpressionEvaluationContext EECtx{ + *this, ExpressionEvaluationContext::ConstantEvaluated, CSD}; + + if (CheckConstraintSatisfaction( + NamedConcept, {NamedConcept->getConstraintExpr()}, MLTAL, + SourceRange(SS.isSet() ? SS.getBeginLoc() + : ConceptNameInfo.getLoc(), + TemplateArgs->getRAngleLoc()), + Satisfaction)) + return ExprError(); + } auto *CL = ConceptReference::Create( Context, SS.isSet() ? SS.getWithLocInContext(Context) : NestedNameSpecifierLoc{}, TemplateKWLoc, ConceptNameInfo, FoundDecl, NamedConcept, ASTTemplateArgumentListInfo::Create(Context, *TemplateArgs)); return ConceptSpecializationExpr::Create( - Context, CL, CSD, AreArgsDependent ? nullptr : &Satisfaction); + Context, CL, CSD, !ShouldEvaluate ? nullptr : &Satisfaction); } ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 6d59180bc446d..9c3d2ea77d44e 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2878,20 +2878,18 @@ namespace { bool Sema::SubstTypeConstraint( TemplateTypeParmDecl *Inst, const TypeConstraint *TC, - const MultiLevelTemplateArgumentList &TemplateArgs, - bool EvaluateConstraints) { - const ASTTemplateArgumentListInfo *TemplArgInfo = - TC->getTemplateArgsAsWritten(); - - if (!EvaluateConstraints) { - Inst->setTypeConstraint(TC->getConceptReference(), - TC->getImmediatelyDeclaredConstraint()); - return false; + const MultiLevelTemplateArgumentList &TemplateArgs, bool RebuildConstraint, + bool EvaluateConstraint) { + if (!RebuildConstraint) { + Inst->setTypeConstraint(TC->getConceptReference(), + TC->getImmediatelyDeclaredConstraint()); + return false; } TemplateArgumentListInfo InstArgs; - if (TemplArgInfo) { + if (const ASTTemplateArgumentListInfo *TemplArgInfo = + TC->getTemplateArgsAsWritten()) { InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc); InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc); if (SubstTemplateArguments(TemplArgInfo->arguments(), TemplateArgs, @@ -2904,7 +2902,8 @@ bool Sema::SubstTypeConstraint( Inst->isParameterPack() ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint()) ->getEllipsisLoc() - : SourceLocation()); + : SourceLocation(), + EvaluateConstraint); } ParmVarDecl *Sema::SubstParmVarDecl( diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index d67b21b4449e0..ff7b450fc31d4 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2903,10 +2903,20 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( Inst->setImplicit(D->isImplicit()); if (auto *TC = D->getTypeConstraint()) { if (!D->isImplicit()) { + bool RebuildConstraint = [&] { + if (EvaluateConstraints) + return true; + for (auto Active = SemaRef.CodeSynthesisContexts.rbegin(); + Active != SemaRef.CodeSynthesisContexts.rend(); ++Active) { + if (llvm::isa_and_present<TypeAliasTemplateDecl>(Active->Entity)) + return true; + } + return false; + }(); // Invented template parameter type constraints will be instantiated // with the corresponding auto-typed parameter as it might reference // other parameters. - if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs, + if (SemaRef.SubstTypeConstraint(Inst, TC, TemplateArgs, RebuildConstraint, EvaluateConstraints)) return nullptr; } diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp index 0b7580f91043c..0e93206cbd1a9 100644 --- a/clang/test/SemaTemplate/concepts-lambda.cpp +++ b/clang/test/SemaTemplate/concepts-lambda.cpp @@ -167,3 +167,22 @@ void foo() { }(x); } } // namespace GH73418 + +namespace GH70601 { + +template <class> +concept C = true; + +template <class T, class U> +concept D = C<T> && C<U>; + +template <class T> +using Type = decltype([]<C U> { + return []<D<U> V>(V val) { + return val; + }(U()); +}.template operator()<T>()); + +static_assert(__is_same(Type<int>, int)); + +} // namespace GH70601 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits