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 <[email protected]>
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@-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}}
+}

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to