Make sure that we always pop a function's scope *before* we call
ActOnFinishFunctionBody/ActOnBlockStmtExpr. This way, we ensure that
we diagnose undefined labels before the jump-scope checker gets run,
since the jump-scope checker requires (as its invariant) that all of
the GotoStmts be wired up correctly.
Fixes PR9495.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127738 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 3994738..baa038e 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -261,7 +261,7 @@
Actions.ActOnStartOfFunctionDef(getCurScope(), LM.D);
if (Tok.is(tok::kw_try)) {
- ParseFunctionTryBlock(LM.D);
+ ParseFunctionTryBlock(LM.D, FnScope);
assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc,
Tok.getLocation()) &&
"ParseFunctionTryBlock went over the cached tokens!");
@@ -276,13 +276,14 @@
// Error recovery.
if (!Tok.is(tok::l_brace)) {
+ FnScope.Exit();
Actions.ActOnFinishFunctionBody(LM.D, 0);
return;
}
} else
Actions.ActOnDefaultCtorInitializers(LM.D);
- ParseFunctionStatementBody(LM.D);
+ ParseFunctionStatementBody(LM.D, FnScope);
if (Tok.getLocation() != origLoc) {
// Due to parsing error, we either went over the cached tokens or
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 7cb9551..ecc02ac 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -1954,6 +1954,7 @@
}
StmtResult Stmt(ParseCompoundStatementBody());
+ BlockScope.Exit();
if (!Stmt.isInvalid())
Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.take(), getCurScope());
else
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 4b702e0..d4391ee 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -1724,9 +1724,12 @@
// specified Declarator for the method.
Actions.ActOnStartOfObjCMethodDef(getCurScope(), MDecl);
- if (PP.isCodeCompletionEnabled())
- if (trySkippingFunctionBodyForCodeCompletion())
+ if (PP.isCodeCompletionEnabled()) {
+ if (trySkippingFunctionBodyForCodeCompletion()) {
+ BodyScope.Exit();
return Actions.ActOnFinishFunctionBody(MDecl, 0);
+ }
+ }
StmtResult FnBody(ParseCompoundStatementBody());
@@ -1735,12 +1738,11 @@
FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc,
MultiStmtArg(Actions), false);
- // TODO: Pass argument information.
- Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
-
// Leave the function body scope.
BodyScope.Exit();
-
+
+ // TODO: Pass argument information.
+ Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
return MDecl;
}
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index d7e9070..cd970ca 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1531,14 +1531,17 @@
return true;
}
-Decl *Parser::ParseFunctionStatementBody(Decl *Decl) {
+Decl *Parser::ParseFunctionStatementBody(Decl *Decl, ParseScope &BodyScope) {
assert(Tok.is(tok::l_brace));
SourceLocation LBraceLoc = Tok.getLocation();
- if (PP.isCodeCompletionEnabled())
- if (trySkippingFunctionBodyForCodeCompletion())
+ if (PP.isCodeCompletionEnabled()) {
+ if (trySkippingFunctionBodyForCodeCompletion()) {
+ BodyScope.Exit();
return Actions.ActOnFinishFunctionBody(Decl, 0);
-
+ }
+ }
+
PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc,
"parsing function body");
@@ -1552,6 +1555,7 @@
FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
MultiStmtArg(Actions), false);
+ BodyScope.Exit();
return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
}
@@ -1560,7 +1564,7 @@
/// function-try-block:
/// 'try' ctor-initializer[opt] compound-statement handler-seq
///
-Decl *Parser::ParseFunctionTryBlock(Decl *Decl) {
+Decl *Parser::ParseFunctionTryBlock(Decl *Decl, ParseScope &BodyScope) {
assert(Tok.is(tok::kw_try) && "Expected 'try'");
SourceLocation TryLoc = ConsumeToken();
@@ -1571,9 +1575,12 @@
if (Tok.is(tok::colon))
ParseConstructorInitializer(Decl);
- if (PP.isCodeCompletionEnabled())
- if (trySkippingFunctionBodyForCodeCompletion())
+ if (PP.isCodeCompletionEnabled()) {
+ if (trySkippingFunctionBodyForCodeCompletion()) {
+ BodyScope.Exit();
return Actions.ActOnFinishFunctionBody(Decl, 0);
+ }
+ }
SourceLocation LBraceLoc = Tok.getLocation();
StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc));
@@ -1583,6 +1590,7 @@
FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc,
MultiStmtArg(Actions), false);
+ BodyScope.Exit();
return Actions.ActOnFinishFunctionBody(Decl, FnBody.take());
}
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index d9b37d2..3946fc7 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -801,7 +801,7 @@
D.getMutableDeclSpec().abort();
if (Tok.is(tok::kw_try))
- return ParseFunctionTryBlock(Res);
+ return ParseFunctionTryBlock(Res, BodyScope);
// If we have a colon, then we're probably parsing a C++
// ctor-initializer.
@@ -810,13 +810,14 @@
// Recover from error.
if (!Tok.is(tok::l_brace)) {
+ BodyScope.Exit();
Actions.ActOnFinishFunctionBody(Res, 0);
return Res;
}
} else
Actions.ActOnDefaultCtorInitializers(Res);
- return ParseFunctionStatementBody(Res);
+ return ParseFunctionStatementBody(Res, BodyScope);
}
/// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides