shafik created this revision. shafik added reviewers: cor3ntin, aaron.ballman, erichkeane, rsmith. Herald added a project: All. shafik requested review of this revision.
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 https://reviews.llvm.org/D158808 Files: clang/lib/Parse/ParseExprCXX.cpp clang/test/Parser/cxx0x-lambda-expressions.cpp clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp Index: clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp =================================================================== --- clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp +++ 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@-1{{no matching function for call to 'Call'}} } Index: clang/test/Parser/cxx0x-lambda-expressions.cpp =================================================================== --- clang/test/Parser/cxx0x-lambda-expressions.cpp +++ clang/test/Parser/cxx0x-lambda-expressions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 -Wno-c99-designator %s +// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -Wno-c++20-extensions -std=c++11 -Wno-c99-designator %s // RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++20 -Wno-c99-designator %s // RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++23 -Wno-c99-designator %s @@ -181,3 +181,11 @@ template <typename T> void m_fn1(T x = 0[0); // expected-error{{expected ']'}} expected-note{{to match this '['}} } *U; + +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'}} +} +} Index: clang/lib/Parse/ParseExprCXX.cpp =================================================================== --- clang/lib/Parse/ParseExprCXX.cpp +++ clang/lib/Parse/ParseExprCXX.cpp @@ -1546,7 +1546,7 @@ 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());
Index: clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp =================================================================== --- clang/test/SemaCXX/subst-func-type-invalid-ret-type.cpp +++ 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@-1{{no matching function for call to 'Call'}} } Index: clang/test/Parser/cxx0x-lambda-expressions.cpp =================================================================== --- clang/test/Parser/cxx0x-lambda-expressions.cpp +++ clang/test/Parser/cxx0x-lambda-expressions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++11 -Wno-c99-designator %s +// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -Wno-c++20-extensions -std=c++11 -Wno-c99-designator %s // RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++20 -Wno-c99-designator %s // RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify -std=c++23 -Wno-c99-designator %s @@ -181,3 +181,11 @@ template <typename T> void m_fn1(T x = 0[0); // expected-error{{expected ']'}} expected-note{{to match this '['}} } *U; + +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'}} +} +} Index: clang/lib/Parse/ParseExprCXX.cpp =================================================================== --- clang/lib/Parse/ParseExprCXX.cpp +++ clang/lib/Parse/ParseExprCXX.cpp @@ -1546,7 +1546,7 @@ 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());
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits