[clang] 6f30ef3 - [Clang] Modify Parser::ParseLambdaExpressionAfterIntroducer to check whether the lambda-declarator is valid

Shafik Yaghmour via cfe-commits cfe-commits at lists.llvm.org
Tue Aug 29 11:34:07 PDT 2023


Author: Shafik Yaghmour
Date: 2023-08-29T11:28:57-07:00
New Revision: 6f30ef360127ffb3346fd3d3e60a229ed44dc667

URL: https://github.com/llvm/llvm-project/commit/6f30ef360127ffb3346fd3d3e60a229ed44dc667
DIFF: https://github.com/llvm/llvm-project/commit/6f30ef360127ffb3346fd3d3e60a229ed44dc667.diff

LOG: [Clang] Modify Parser::ParseLambdaExpressionAfterIntroducer to check whether the lambda-declarator is valid

We had a couple of crashes due to invalid lambda trailing return types that
were diagnosed but not treated as errors during parsing. So now in
Parser::ParseLambdaExpressionAfterIntroducer(...) after ActOnStartOfLambdaDefinition(...)
we also check if the lambda-declarator is invalid and if so we end up in ActOnLambdaError(...).

Fixes: https://github.com/llvm/llvm-project/issues/64962
https://github.com/llvm/llvm-project/issues/28679

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

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Parse/ParseExprCXX.cpp
    clang/test/Parser/cxx2a-template-lambdas.cpp
    clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 6f97acc09bc934..dc7569cf79f43e 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -234,6 +234,10 @@ Bug Fixes to C++ Support
   and appear in an implicit cast.
   (`#64949 <https://github.com/llvm/llvm-project/issues/64949>`_).
 
+- Fix crash when parsing ill-formed lambda trailing return type. Fixes:
+  (`#64962 <https://github.com/llvm/llvm-project/issues/64962>`_) and
+  (`#28679 <https://github.com/llvm/llvm-project/issues/28679>`_).
+
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed an import failure of recursive friend class template.

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 678ecad19ecd82..d2715db95f5285 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -1546,7 +1546,8 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
   TemplateParamScope.Exit();
   LambdaScope.Exit();
 
-  if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid())
+  if (!Stmt.isInvalid() && !TrailingReturnType.isInvalid() &&
+      !D.isInvalidType())
     return Actions.ActOnLambdaExpr(LambdaBeginLoc, Stmt.get(), getCurScope());
 
   Actions.ActOnLambdaError(LambdaBeginLoc, getCurScope());

diff  --git a/clang/test/Parser/cxx2a-template-lambdas.cpp b/clang/test/Parser/cxx2a-template-lambdas.cpp
index 5cf1a862d878cb..98c74a247b535f 100644
--- a/clang/test/Parser/cxx2a-template-lambdas.cpp
+++ b/clang/test/Parser/cxx2a-template-lambdas.cpp
@@ -32,3 +32,11 @@ auto XL1 = []<auto> requires true noexcept requires true {}; // expected-error {
 // expected-warning at -3 {{is a C++23 extension}}
 // expected-warning at -3 {{is a C++23 extension}}
 #endif
+
+namespace GH64962 {
+void f() {
+  [] <typename T>(T i) -> int[] // expected-error {{function cannot return array type 'int[]'}}
+                                // extension-warning {{explicit template parameter list for lambdas is a C++20 extension}}
+    { return 3; } (v); // expected-error {{use of undeclared identifier 'v'}}
+}
+}

diff  --git a/clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp b/clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp
index c78ffff3ff50ee..565e06b101a7b2 100644
--- a/clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp
+++ b/clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp
@@ -5,12 +5,11 @@
 template<typename T> T declval();
 
 template <typename T>
-auto Call(T x) -> decltype(declval<T>()(0)) {} // expected-note{{candidate template ignored}}
+auto Call(T x) -> decltype(declval<T>()(0)) {}
 
 class Status {};
 
 void fun() {
   // The Status() (instead of Status) here used to cause a crash.
   Call([](auto x) -> Status() {}); // expected-error{{function cannot return function type 'Status ()}}
-  // expected-error at -1{{no matching function for call to 'Call'}}
 }


        


More information about the cfe-commits mailing list