[clang] 75cd8cd - [Clang] Correctly handle generic lambda used as default template argument.

Corentin Jabot via cfe-commits cfe-commits at lists.llvm.org
Fri May 26 07:04:15 PDT 2023


Author: Corentin Jabot
Date: 2023-05-26T16:04:10+02:00
New Revision: 75cd8cdbde45d07800d5cefa6f7a213271245e4a

URL: https://github.com/llvm/llvm-project/commit/75cd8cdbde45d07800d5cefa6f7a213271245e4a
DIFF: https://github.com/llvm/llvm-project/commit/75cd8cdbde45d07800d5cefa6f7a213271245e4a.diff

LOG: [Clang] Correctly handle generic lambda used as default template argument.

Adjust the template pparameter depth when parsing default
template arguments as they may introduce generic lambda whose parameters
are not substituted at the same depth.

Fixes #62611

Reviewed By: erichkeane, #clang-language-wg

Differential Revision: https://reviews.llvm.org/D151342

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseTemplate.cpp
    clang/test/SemaCXX/cxx2a-template-lambdas.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f1cc205c4a430..4387f9b3145be 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -507,6 +507,8 @@ Bug Fixes to C++ Support
   (`#114 <https://github.com/llvm/llvm-project/issues/114>`_)
 - Fix parsing of `auto(x)`, when it is surrounded by parentheses.
   (`#62494 <https://github.com/llvm/llvm-project/issues/62494>`_)
+- Fix handling of generic lambda used as template arguments.
+  (`#62611 <https://github.com/llvm/llvm-project/issues/62611>`_)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 964d985b6b6e6..79f4ab683281e 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -841,10 +841,17 @@ NamedDecl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) {
   // we introduce the type parameter into the local scope.
   SourceLocation EqualLoc;
   ParsedType DefaultArg;
-  if (TryConsumeToken(tok::equal, EqualLoc))
+  if (TryConsumeToken(tok::equal, EqualLoc)) {
+    // The default argument may declare template parameters, notably
+    // if it contains a generic lambda, so we need to increase
+    // the template depth as these parameters would not be instantiated
+    // at the current level.
+    TemplateParameterDepthRAII CurTemplateDepthTracker(TemplateParameterDepth);
+    ++CurTemplateDepthTracker;
     DefaultArg =
         ParseTypeName(/*Range=*/nullptr, DeclaratorContext::TemplateTypeArg)
             .get();
+  }
 
   NamedDecl *NewDecl = Actions.ActOnTypeParameter(getCurScope(),
                                                   TypenameKeyword, EllipsisLoc,
@@ -1030,6 +1037,14 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) {
       //   end of the template-parameter-list rather than a greater-than
       //   operator.
       GreaterThanIsOperatorScope G(GreaterThanIsOperator, false);
+
+      // The default argument may declare template parameters, notably
+      // if it contains a generic lambda, so we need to increase
+      // the template depth as these parameters would not be instantiated
+      // at the current level.
+      TemplateParameterDepthRAII CurTemplateDepthTracker(
+          TemplateParameterDepth);
+      ++CurTemplateDepthTracker;
       EnterExpressionEvaluationContext ConstantEvaluated(
           Actions, Sema::ExpressionEvaluationContext::ConstantEvaluated);
       DefaultArg =

diff  --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
index 65baf29718f06..cc50292dbff48 100644
--- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
+++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
@@ -43,3 +43,30 @@ constexpr T outer() {
 }
 static_assert(outer<int>() == 123);
 template int *outer<int *>(); // expected-note {{in instantiation}}
+
+
+namespace GH62611 {
+template <auto A = [](auto x){}>
+struct C {
+  static constexpr auto B = A;
+};
+
+int test() {
+  C<>::B(42);
+}
+
+namespace AutoParam
+{
+template <auto A = [](auto x) { return x;}>
+auto B = A;
+static_assert(B<>(42) == 42);
+}
+
+namespace TypeParam
+{
+template <typename T = decltype([](auto x) {return x;})>
+auto B = T{};
+static_assert(B<>(42) == 42);
+}
+
+}


        


More information about the cfe-commits mailing list