aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorYounan Zhang <zyn7109@gmail.com>2025-07-10 16:17:34 +0800
committerGitHub <noreply@github.com>2025-07-10 16:17:34 +0800
commitadcd1bb32a050ced58584882b405f04f42c6009b (patch)
tree3b7b6f6c3e81027e7c2aaa4e2f082d274216751c /clang/lib/Sema/SemaTemplateInstantiate.cpp
parent1ccd7793247139e55aec986e6d86c50d97f9a755 (diff)
downloadllvm-adcd1bb32a050ced58584882b405f04f42c6009b.zip
llvm-adcd1bb32a050ced58584882b405f04f42c6009b.tar.gz
llvm-adcd1bb32a050ced58584882b405f04f42c6009b.tar.bz2
[Clang] Fix the template argument collection after CWG2369 (#147894)
Since the function template isn't instantiated before constraint checking, we'll not be able to find the outer template arguments through function specialization when evaluating the inner constraint that is nested within a larger constraint expression. The only practical solution is to get them back through the code synthesis context, which also allows us to eliminate an overload of getTemplateInstantiationArgs. No release note because it's a regression on trunk. Fixes https://github.com/llvm/llvm-project/issues/147772
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp34
1 files changed, 17 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 9140f00..f04b01f 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -309,10 +309,24 @@ Response HandleFunction(Sema &SemaRef, const FunctionDecl *Function,
isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function))
return Response::Done();
- } else if (Function->getDescribedFunctionTemplate()) {
+ } else if (auto *Template = Function->getDescribedFunctionTemplate()) {
assert(
(ForConstraintInstantiation || Result.getNumSubstitutedLevels() == 0) &&
"Outer template not instantiated?");
+ if (ForConstraintInstantiation) {
+ for (auto &Inst : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+ if (Inst.Kind == Sema::CodeSynthesisContext::ConstraintsCheck &&
+ Inst.Entity == Template) {
+ // After CWG2369, the outer templates are not instantiated when
+ // checking its associated constraints. So add them back through the
+ // synthesis context; this is useful for e.g. nested constraints
+ // involving lambdas.
+ Result.addOuterTemplateArguments(Template, Inst.template_arguments(),
+ /*Final=*/false);
+ break;
+ }
+ }
+ }
}
// If this is a friend or local declaration and it declares an entity at
// namespace scope, take arguments from its lexical parent
@@ -474,21 +488,6 @@ MultiLevelTemplateArgumentList Sema::getTemplateInstantiationArgs(
assert((ND || DC) && "Can't find arguments for a decl if one isn't provided");
// Accumulate the set of template argument lists in this structure.
MultiLevelTemplateArgumentList Result;
- getTemplateInstantiationArgs(
- Result, ND, DC, Final, Innermost, RelativeToPrimary, Pattern,
- ForConstraintInstantiation, SkipForSpecialization,
- ForDefaultArgumentSubstitution);
- return Result;
-}
-
-void Sema::getTemplateInstantiationArgs(
- MultiLevelTemplateArgumentList &Result, const NamedDecl *ND,
- const DeclContext *DC, bool Final,
- std::optional<ArrayRef<TemplateArgument>> Innermost, bool RelativeToPrimary,
- const FunctionDecl *Pattern, bool ForConstraintInstantiation,
- bool SkipForSpecialization, bool ForDefaultArgumentSubstitution) {
- assert((ND || DC) && "Can't find arguments for a decl if one isn't provided");
- // Accumulate the set of template argument lists in this structure.
using namespace TemplateInstArgsHelpers;
const Decl *CurDecl = ND;
@@ -548,12 +547,13 @@ void Sema::getTemplateInstantiationArgs(
}
if (R.IsDone)
- return;
+ return Result;
if (R.ClearRelativeToPrimary)
RelativeToPrimary = false;
assert(R.NextDecl);
CurDecl = R.NextDecl;
}
+ return Result;
}
bool Sema::CodeSynthesisContext::isInstantiationRecord() const {