Fix crash when deserializing a lambda expression in a decltype.

This commit is contained in:
Richard Smith 2022-02-15 17:55:35 -08:00
parent 20bdd3e232
commit 13b6f31548
2 changed files with 27 additions and 2 deletions

View File

@ -38,6 +38,10 @@ namespace {
void VisitStmt(const Stmt *S);
void VisitStmtNoChildren(const Stmt *S) {
HandleStmtClass(S->getStmtClass());
}
virtual void HandleStmtClass(Stmt::StmtClass SC) = 0;
#define STMT(Node, Base) void Visit##Node(const Node *S);
@ -218,7 +222,7 @@ namespace {
void StmtProfiler::VisitStmt(const Stmt *S) {
assert(S && "Requires non-null Stmt pointer");
HandleStmtClass(S->getStmtClass());
VisitStmtNoChildren(S);
for (const Stmt *SubStmt : S->children()) {
if (SubStmt)
@ -1945,7 +1949,11 @@ StmtProfiler::VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *S) {
void
StmtProfiler::VisitLambdaExpr(const LambdaExpr *S) {
VisitExpr(S);
// Do not recursively visit the children of this expression. Profiling the
// body would result in unnecessary work, and is not safe to do during
// deserialization.
VisitStmtNoChildren(S);
// C++20 [temp.over.link]p5:
// Two lambda-expressions are never considered equivalent.
VisitDecl(S->getLambdaClass());

View File

@ -0,0 +1,17 @@
// RUN: %clang_cc1 -std=c++20 -include %s %s -o %t
// RUN: %clang_cc1 -std=c++20 -emit-pch %s -o %t
// RUN: %clang_cc1 -std=c++20 -include-pch %t -verify %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
template<typename T> auto f() -> decltype([]{ return T(42); });
#else /*included pch*/
static_assert(decltype(f<int>())()() == 42);
#endif // HEADER