[clang] 19e518d - [Clang][Parser] Have the depth of the abbreviated generic lambdas inside a requires clause differ from the surrounding generic lambda (#80656)

via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 22 17:36:37 PST 2024


Author: Younan Zhang
Date: 2024-02-23T09:36:32+08:00
New Revision: 19e518d2623c0e87a87ebf30405e74448bd1ee70

URL: https://github.com/llvm/llvm-project/commit/19e518d2623c0e87a87ebf30405e74448bd1ee70
DIFF: https://github.com/llvm/llvm-project/commit/19e518d2623c0e87a87ebf30405e74448bd1ee70.diff

LOG: [Clang][Parser] Have the depth of the abbreviated generic lambdas inside a requires clause differ from the surrounding generic lambda (#80656)

A one-line fix, again : )

This fixes https://github.com/llvm/llvm-project/issues/78524 and the
similar example at
https://github.com/llvm/llvm-project/issues/78524#issuecomment-1899886951.

We previously increased the template depth by one after parsing the
attaching requires-clause on a lambda expression. This led to a problem
where the 'auto' parameters of nested abbreviated generic lambdas,
inside of a requires-expression, had the same depth as the template
parameters of the surrounding lambda. Consequently, during the
concept-checking stage, we ended up substituting these parameters with
the wrong template arguments because they were at different levels.

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseExprCXX.cpp
    clang/test/Parser/cxx-concepts-requires-clause.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 19cc5b77564316..529dd783ab7382 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -277,6 +277,10 @@ Bug Fixes to C++ Support
   (`#82258 <https://github.com/llvm/llvm-project/issues/82258>`_)
 - Correctly immediate-escalate lambda conversion functions.
   (`#82258 <https://github.com/llvm/llvm-project/issues/82258>`_)
+- Fixed an issue where template parameters of a nested abbreviated generic lambda within
+  a requires-clause lie at the same depth as those of the surrounding lambda. This,
+  in turn, results in the wrong template argument substitution during constraint checking.
+  (`#78524 <https://github.com/llvm/llvm-project/issues/78524>`_)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index fd262ff31e661a..22ee60af4616d2 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1385,6 +1385,16 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
       Diag(RAngleLoc,
            diag::err_lambda_template_parameter_list_empty);
     } else {
+      // We increase the template depth before recursing into a requires-clause.
+      //
+      // This depth is used for setting up a LambdaScopeInfo (in
+      // Sema::RecordParsingTemplateParameterDepth), which is used later when
+      // inventing template parameters in InventTemplateParameter.
+      //
+      // This way, abbreviated generic lambdas could have 
diff erent template
+      // depths, avoiding substitution into the wrong template parameters during
+      // constraint satisfaction check.
+      ++CurTemplateDepthTracker;
       ExprResult RequiresClause;
       if (TryConsumeToken(tok::kw_requires)) {
         RequiresClause =
@@ -1396,7 +1406,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
 
       Actions.ActOnLambdaExplicitTemplateParameterList(
           Intro, LAngleLoc, TemplateParams, RAngleLoc, RequiresClause);
-      ++CurTemplateDepthTracker;
     }
   }
 

diff  --git a/clang/test/Parser/cxx-concepts-requires-clause.cpp b/clang/test/Parser/cxx-concepts-requires-clause.cpp
index 1ec1eefa128653..5b5bc9ea978bf2 100644
--- a/clang/test/Parser/cxx-concepts-requires-clause.cpp
+++ b/clang/test/Parser/cxx-concepts-requires-clause.cpp
@@ -168,3 +168,30 @@ auto lambda4 = [] requires(sizeof(char) == 1){}; // expected-error {{expected bo
 #if __cplusplus <= 202002L
 // expected-warning at -2{{lambda without a parameter clause is a C++23 extension}}
 #endif
+
+namespace GH78524 {
+
+template <typename T> T Foo;
+
+template <typename T> auto C(Foo<T>);
+
+template <typename T> struct D {
+  decltype(T()(C<T>)) Type;
+};
+
+template <typename T, typename U> D<T> G(T, U) { return {}; }
+
+struct E {};
+
+void F() {
+  G([]<typename T>
+//     ~~~~~~~~~~ T: Depth: 0, Index: 0
+      requires requires { [](auto...) {}; }(T)
+//                           ~~~~ auto: Depth: 1, Index: 0
+    { return T(); },
+    E{});
+}
+
+int a = []<int=0> requires requires { [](auto){}; } { return 0; }();
+
+} // namespace GH78524


        


More information about the cfe-commits mailing list