Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -4308,7 +4308,8 @@ return false; This->moveInto(Result); return true; - } else if (MD && isLambdaCallOperator(MD)) { + } else if (MD && isLambdaCallOperator(MD) + && !Info.checkingPotentialConstantExpression()) { // We're in a lambda; determine the lambda capture field maps. MD->getParent()->getCaptureFields(Frame.LambdaCaptureFields, Frame.LambdaThisCaptureField); @@ -5202,9 +5203,11 @@ // data-member/field within the closure object, and if so, evaluate to the // field or what the field refers to. if (Info.CurrentCall && isLambdaCallOperator(Info.CurrentCall->Callee)) { + // We don't track the lambda's captures in a potential constant expression. + if (Info.checkingPotentialConstantExpression()) + return false; + if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) { - if (Info.checkingPotentialConstantExpression()) - return false; // Start with 'Result' referring to the complete closure object... Result = *Info.CurrentCall->This; // ... then update it to refer to the field of the closure object Index: clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp =================================================================== --- clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp +++ clang/test/SemaCXX/cxx1z-constexpr-lambdas.cpp @@ -270,4 +270,37 @@ } // end ns test_lambda_is_cce +namespace PR36054 { +constexpr int fn() { + int Capture = 42; + return [=]() constexpr { return Capture; }(); +} + +static_assert(fn() == 42, ""); + +template +constexpr int tfn() { + int Capture = 42; + return [=]() constexpr { return Capture; }(); +} + +static_assert(tfn() == 42, ""); + +constexpr int gfn() { + int Capture = 42; + return [=](auto P) constexpr { return Capture + P; }(58); +} + +static_assert(gfn() == 100, ""); + +constexpr bool OtherCaptures() { + int Capture = 42; + constexpr auto Outer = [](auto P) constexpr { return 42 + P; }; + auto Inner = [&](auto O) constexpr { return O(58) + Capture; }; + return Inner(Outer) == 142; +} + +static_assert(OtherCaptures(), ""); +} // namespace PR36054 + #endif // ndef CPP14_AND_EARLIER