leonardchan created this revision.
leonardchan added reviewers: rsmith, aaron.ballman.
leonardchan added a project: clang.
leonardchan added a dependent revision: D49511: [Sema/Attribute] Check for 
noderef attribute.
leonardchan removed a dependent revision: D49511: [Sema/Attribute] Check for 
noderef attribute.
leonardchan added a dependency: D49511: [Sema/Attribute] Check for noderef 
attribute.

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.

Ideally this will be one of the first patches for pushing and popping records 
so that we operate less off the global Sema record. I tried doing this as 
@rsmith recommends in https://reviews.llvm.org/D49511?id=160892#inline-451745, 
but ended up running into many issues that would be better addressed accross 
multiple patches.

Parent of https://reviews.llvm.org/D49511 where we would like to check for 
`noderef` usage on each context.


Repository:
  rC Clang

https://reviews.llvm.org/D54014

Files:
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclObjC.cpp
  clang/lib/Sema/SemaExpr.cpp

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() {
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<ObjCMethodDecl>(D);
 
+  PushExpressionEvaluationContext(ExprEvalContexts.back().Context);
+
   // If we don't have a valid method decl, simply return.
   if (!MDecl)
     return;
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<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;
@@ -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;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to