diff --git a/clang/lib/AST/Interp/ByteCodeEmitter.cpp b/clang/lib/AST/Interp/ByteCodeEmitter.cpp index ae777d555e9165..17da77bc63c9bb 100644 --- a/clang/lib/AST/Interp/ByteCodeEmitter.cpp +++ b/clang/lib/AST/Interp/ByteCodeEmitter.cpp @@ -93,6 +93,11 @@ Function *ByteCodeEmitter::compileFunc(const FunctionDecl *FuncDecl) { // Set up lambda capture to closure record field mapping. if (isLambdaCallOperator(MD)) { + // The parent record needs to be complete, we need to know about all + // the lambda captures. + if (!MD->getParent()->isCompleteDefinition()) + return nullptr; + const Record *R = P.getOrCreateRecord(MD->getParent()); llvm::DenseMap LC; FieldDecl *LTC; diff --git a/clang/lib/AST/Interp/Context.cpp b/clang/lib/AST/Interp/Context.cpp index 913e8d514282ad..b5e992c5a9ac16 100644 --- a/clang/lib/AST/Interp/Context.cpp +++ b/clang/lib/AST/Interp/Context.cpp @@ -31,6 +31,9 @@ bool Context::isPotentialConstantExpr(State &Parent, const FunctionDecl *FD) { if (!Func || !Func->hasBody()) Func = Compiler(*this, *P).compileFunc(FD); + if (!Func) + return false; + APValue DummyResult; if (!Run(Parent, Func, DummyResult)) return false; diff --git a/clang/test/AST/Interp/lambda.cpp b/clang/test/AST/Interp/lambda.cpp index 0eb12643b1b7f4..d68fe995e8fa1c 100644 --- a/clang/test/AST/Interp/lambda.cpp +++ b/clang/test/AST/Interp/lambda.cpp @@ -280,3 +280,9 @@ namespace InvalidCapture { } (); } } + +constexpr int fn() { + int Capture = 42; + return [=]() constexpr { return Capture; }(); +} +static_assert(fn() == 42, "");