Author: Richard Smith Date: 2022-02-15T17:56:45-08:00 New Revision: 13b6f31548784452990da6dba555af8d7a061958
URL: https://github.com/llvm/llvm-project/commit/13b6f31548784452990da6dba555af8d7a061958 DIFF: https://github.com/llvm/llvm-project/commit/13b6f31548784452990da6dba555af8d7a061958.diff LOG: Fix crash when deserializing a lambda expression in a decltype. Added: clang/test/PCH/cxx20-unevaluated-lambda.cpp Modified: clang/lib/AST/StmtProfile.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 09853e0f0e497..b590f4a002638 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -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()); diff --git a/clang/test/PCH/cxx20-unevaluated-lambda.cpp b/clang/test/PCH/cxx20-unevaluated-lambda.cpp new file mode 100644 index 0000000000000..29af5e61c3307 --- /dev/null +++ b/clang/test/PCH/cxx20-unevaluated-lambda.cpp @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits