r348434 - [Sema] Push and Pop Expression Evaluation Context Records at the start and end of function definitions

Leonard Chan via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 5 16:10:36 PST 2018


Author: leonardchan
Date: Wed Dec  5 16:10:36 2018
New Revision: 348434

URL: http://llvm.org/viewvc/llvm-project?rev=348434&view=rev
Log:
[Sema] Push and Pop Expression Evaluation Context Records at the start and end of function definitions

This patch creates a new context for every function definition we enter.
Currently we do not push and pop on these, usually working off of the global
context record added in the Sema constructor, which never gets popped.

Differential Revision: https://reviews.llvm.org/D54014

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclObjC.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=348434&r1=348433&r2=348434&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Dec  5 16:10:36 2018
@@ -12828,6 +12828,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scop
     // 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 @@ Decl *Sema::ActOnStartOfFunctionDef(Scop
   else
     FD = cast<FunctionDecl>(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<AliasAttr>()) {
     Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0;
@@ -13046,6 +13052,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
   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 @@ Decl *Sema::ActOnFinishFunctionBody(Decl
   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);

Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=348434&r1=348433&r2=348434&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Dec  5 16:10:36 2018
@@ -363,6 +363,8 @@ void Sema::ActOnStartOfObjCMethodDef(Sco
   assert((getCurMethodDecl() == nullptr) && "Methodparsing confused");
   ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
 
+  PushExpressionEvaluationContext(ExprEvalContexts.back().Context);
+
   // If we don't have a valid method decl, simply return.
   if (!MDecl)
     return;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=348434&r1=348433&r2=348434&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Dec  5 16:10:36 2018
@@ -14414,11 +14414,8 @@ void Sema::PopExpressionEvaluationContex
   // 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() {




More information about the cfe-commits mailing list