Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -12767,6 +12767,7 @@ // Parsing the function declaration failed in some way. Push on a fake scope // anyway so we can try to parse the function body. PushFunctionScope(); + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); return D; } @@ -12777,6 +12778,11 @@ else FD = cast(D); + // Do not push if it is a lambda because one is already pushed when building + // the lambda in ActOnStartOfLambdaDefinition(). + if (!isLambdaCallOperator(FD)) + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); + // Check for defining attributes before the check for redefinition. if (const auto *Attr = FD->getAttr()) { Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0; @@ -12995,6 +13001,11 @@ if (getLangOpts().CoroutinesTS && getCurFunction()->isCoroutine()) CheckCompletedCoroutineBody(FD, Body); + // Do not call PopExpressionEvaluationContext() if it is a lambda because one + // is already popped when finishing the lambda in BuildLambdaExpr(). This is + // meant to pop the context added in ActOnStartOfFunctionDef(). + bool IsLambda = isLambdaCallOperator(FD); + if (FD) { FD->setBody(Body); FD->setWillHaveBody(false); @@ -13166,11 +13177,17 @@ auto superIsNSObject = [&](const ObjCMethodDecl *MD) { auto IFace = MD->getClassInterface(); - if (!IFace) + if (!IFace) { + if (!IsLambda) + PopExpressionEvaluationContext(); return false; + } auto SuperD = IFace->getSuperClass(); - if (!SuperD) + if (!SuperD) { + if (!IsLambda) + PopExpressionEvaluationContext(); return false; + } return SuperD->getIdentifier() == NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); }; @@ -13195,6 +13212,8 @@ // Parsing the function declaration failed in some way. Pop the fake scope // we pushed on. PopFunctionScopeInfo(ActivePolicy, dcl); + if (!IsLambda) + PopExpressionEvaluationContext(); return nullptr; } @@ -13290,6 +13309,9 @@ DiscardCleanupsInEvaluationContext(); } + if (!IsLambda) + PopExpressionEvaluationContext(); + return dcl; } Index: clang/lib/Sema/SemaDeclObjC.cpp =================================================================== --- clang/lib/Sema/SemaDeclObjC.cpp +++ clang/lib/Sema/SemaDeclObjC.cpp @@ -363,6 +363,8 @@ assert((getCurMethodDecl() == nullptr) && "Methodparsing confused"); ObjCMethodDecl *MDecl = dyn_cast_or_null(D); + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); + // If we don't have a valid method decl, simply return. if (!MDecl) return; Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -14301,11 +14301,8 @@ // Pop the current expression evaluation context off the stack. ExprEvalContexts.pop_back(); - if (!ExprEvalContexts.empty()) - ExprEvalContexts.back().NumTypos += NumTypos; - else - assert(NumTypos == 0 && "There are outstanding typos after popping the " - "last ExpressionEvaluationContextRecord"); + // The global expression evaluation context record is never popped. + ExprEvalContexts.back().NumTypos += NumTypos; } void Sema::DiscardCleanupsInEvaluationContext() {