Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -12828,6 +12828,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; } @@ -12838,6 +12839,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; @@ -13046,6 +13052,21 @@ return ActOnFinishFunctionBody(D, BodyArg, false); } +/// RAII object that pops an ExpressionEvaluationContext when exiting a function +/// body. +class ExitFunctionBodyRAII { +public: + ExitFunctionBodyRAII(Sema &S, bool IsLambda) : S(S), IsLambda(IsLambda) {} + ~ExitFunctionBodyRAII() { + if (!IsLambda) + S.PopExpressionEvaluationContext(); + } + +private: + Sema &S; + bool IsLambda = false; +}; + Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation) { FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr; @@ -13056,6 +13077,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(). + ExitFunctionBodyRAII ExitRAII(*this, isLambdaCallOperator(FD)); + if (FD) { FD->setBody(Body); FD->setWillHaveBody(false); Index: lib/Sema/SemaDeclObjC.cpp =================================================================== --- lib/Sema/SemaDeclObjC.cpp +++ 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: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -14414,11 +14414,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() {