[clang] [Clang] Follow up to previous lambda-in-concept patch (PR #210381)
Younan Zhang via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 17 10:16:24 PDT 2026
https://github.com/zyn0217 created https://github.com/llvm/llvm-project/pull/210381
This handles cases where NTTP occurs inside a lambda that is part of the concept arguments, following up to the previous fix as in 24df1d13d9090e0.
No release note because I want to backport it, to complete that lambda patch.
As a drive-by, this removes an unused parameter of ActOnTemplateParameterList.
Fixes https://github.com/llvm/llvm-project/issues/210346
>From bcb4d39f5e0cacc6572aaf02eb78c9647bc13494 Mon Sep 17 00:00:00 2001
From: Younan Zhang <zyn7109 at gmail.com>
Date: Sat, 18 Jul 2026 01:02:53 +0800
Subject: [PATCH] [Clang] Follow up to previous lambda-in-concept patch
This handles cases where NTTP occurs inside a lambda that is part of
the concept arguments, following up to the previous fix as in 24df1d13d9090e0.
No release note because I want to backport it, to complete that lambda
patch.
As a drive-by, this removes an unused parameter of ActOnTemplateParameterList.
---
clang/include/clang/Sema/Sema.h | 2 +-
clang/lib/Parse/ParseDecl.cpp | 4 ++--
clang/lib/Parse/ParseDeclCXX.cpp | 2 +-
clang/lib/Parse/ParseTemplate.cpp | 8 +++----
clang/lib/Sema/SemaTemplate.cpp | 12 ++++------
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 8 +++++--
clang/test/SemaTemplate/concepts-lambda.cpp | 23 +++++++++++++++++++
7 files changed, 41 insertions(+), 18 deletions(-)
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 11550340ac8d2..4d1873c79ef66 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -11709,7 +11709,7 @@ class Sema final : public SemaBase {
/// constrained by RequiresClause, that contains the template parameters in
/// Params.
TemplateParameterList *ActOnTemplateParameterList(
- unsigned Depth, SourceLocation ExportLoc, SourceLocation TemplateLoc,
+ SourceLocation ExportLoc, SourceLocation TemplateLoc,
SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
SourceLocation RAngleLoc, Expr *RequiresClause);
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 88f07bb104fcb..0df3b15fa5aee 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -2283,7 +2283,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// Recover as if it were an explicit specialization.
TemplateParameterLists FakedParamLists;
FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
- 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
+ SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
LAngleLoc, nullptr));
TheDecl = ParseFunctionDefinition(
@@ -2597,7 +2597,7 @@ Decl *Parser::ParseDeclarationAfterDeclaratorAndAttributes(
// Recover as if it were an explicit specialization.
TemplateParameterLists FakedParamLists;
FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
- 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
+ SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
LAngleLoc, nullptr));
ThisDecl =
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index d7a9c72eb2da8..8763b76ea5364 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -2054,7 +2054,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// "template<>", so that we treat this construct as a class
// template specialization.
FakedParamLists.push_back(Actions.ActOnTemplateParameterList(
- 0, SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
+ SourceLocation(), TemplateInfo.TemplateLoc, LAngleLoc, {},
LAngleLoc, nullptr));
TemplateParams = &FakedParamLists;
}
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 735a9bd1f9f1c..677e4bbeaa25e 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -128,8 +128,8 @@ Parser::DeclGroupPtrTy Parser::ParseTemplateDeclarationOrSpecialization(
}
ParamLists.push_back(Actions.ActOnTemplateParameterList(
- CurTemplateDepthTracker.getDepth(), ExportLoc, TemplateLoc, LAngleLoc,
- TemplateParams, RAngleLoc, OptionalRequiresClauseConstraintER.get()));
+ ExportLoc, TemplateLoc, LAngleLoc, TemplateParams, RAngleLoc,
+ OptionalRequiresClauseConstraintER.get()));
} while (Tok.isOneOf(tok::kw_export, tok::kw_template));
ParsedTemplateInfo TemplateInfo(&ParamLists, isSpecialization,
@@ -797,8 +797,8 @@ NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,
DiagnoseMisplacedEllipsis(EllipsisLoc, NameLoc, AlreadyHasEllipsis, true);
TemplateParameterList *ParamList = Actions.ActOnTemplateParameterList(
- Depth, SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams,
- RAngleLoc, OptionalRequiresClauseConstraintER.get());
+ SourceLocation(), TemplateLoc, LAngleLoc, TemplateParams, RAngleLoc,
+ OptionalRequiresClauseConstraintER.get());
// Grab a default argument (if available).
// Per C++0x [basic.scope.pdecl]p9, we parse the default argument before
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 7286a0c2f6fbf..6dc331565594f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1882,14 +1882,10 @@ bool Sema::ConstraintExpressionDependsOnEnclosingTemplate(
return Checker.getResult();
}
-TemplateParameterList *
-Sema::ActOnTemplateParameterList(unsigned Depth,
- SourceLocation ExportLoc,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc,
- Expr *RequiresClause) {
+TemplateParameterList *Sema::ActOnTemplateParameterList(
+ SourceLocation ExportLoc, SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc, ArrayRef<NamedDecl *> Params,
+ SourceLocation RAngleLoc, Expr *RequiresClause) {
if (ExportLoc.isValid())
Diag(ExportLoc, diag::warn_template_export_unsupported);
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index c2e90624b8a6e..42749f711dd80 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3762,13 +3762,17 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
if (IsExpandedParameterPack)
Param = NonTypeTemplateParmDecl::Create(
SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
- D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+ D->getDepth() - (TemplateArgs.retainInnerDepths()
+ ? 0
+ : TemplateArgs.getNumSubstitutedLevels()),
D->getPosition(), D->getIdentifier(), T, TSI,
ExpandedParameterPackTypes, ExpandedParameterPackTypesAsWritten);
else
Param = NonTypeTemplateParmDecl::Create(
SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
- D->getDepth() - TemplateArgs.getNumSubstitutedLevels(),
+ D->getDepth() - (TemplateArgs.retainInnerDepths()
+ ? 0
+ : TemplateArgs.getNumSubstitutedLevels()),
D->getPosition(), D->getIdentifier(), T, D->isParameterPack(), TSI);
if (AutoTypeLoc AutoLoc = TSI->getTypeLoc().getContainedAutoTypeLoc())
diff --git a/clang/test/SemaTemplate/concepts-lambda.cpp b/clang/test/SemaTemplate/concepts-lambda.cpp
index 2010a028fce4a..1c798c76778ea 100644
--- a/clang/test/SemaTemplate/concepts-lambda.cpp
+++ b/clang/test/SemaTemplate/concepts-lambda.cpp
@@ -493,3 +493,26 @@ static_assert(count_if_v_bad_2<L, double> == 111);
static_assert(count_if_v_bad_2<L, char> == 111);
}
+
+namespace GH210346 {
+
+template<auto L, auto... Ts>
+concept foo =
+ requires { L.template operator()<Ts...>(Ts...); }; // #GH210346_foo
+
+template<auto P, auto... Ts>
+concept bar = foo<[]<auto... Us>{}, Ts...>; // #GH210346_bar
+
+template<auto P, auto... Ts>
+ requires bar<P, Ts...> // #GH210346_baz
+constexpr unsigned baz = [] { return 42; }();
+
+constexpr auto L = []<typename T> {};
+
+static_assert(baz<L> == 42);
+static_assert(baz<L, 1> == 42);
+// expected-error at -1 {{constraints not satisfied}}
+// expected-note@#GH210346_baz {{evaluated to false}}
+// expected-note@#GH210346_bar {{evaluated to false}}
+// expected-note@#GH210346_foo {{no matching member function for call}}
+}
More information about the cfe-commits
mailing list