[PATCH] D54014: [Sema] Push and Pop Expression Evaluation Context Records at the start and end of function definitions
Leonard Chan via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 5 16:10:50 PST 2018
leonardchan updated this revision to Diff 176893.
leonardchan marked an inline comment as done.
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D54014/new/
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
@@ -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() {
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
@@ -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<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 @@
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);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D54014.176893.patch
Type: text/x-patch
Size: 3298 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181206/55b9ecf1/attachment.bin>
More information about the cfe-commits
mailing list