summaryrefslogtreecommitdiffstats
path: root/clang/lib/Parse
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-02-17 01:35:32 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-02-17 01:35:32 +0000
commit1002d10aaaf18f6b54f6e458b4630f5db9185999 (patch)
tree6d38606e59b1f661fb3cea58a280df2aaf20c4fd /clang/lib/Parse
parentdd6c1cd4e8d478d928f5e2ed57473ab5418d9897 (diff)
downloadbcm5719-llvm-1002d10aaaf18f6b54f6e458b4630f5db9185999.tar.gz
bcm5719-llvm-1002d10aaaf18f6b54f6e458b4630f5db9185999.zip
Reject continue/break statements within members of local functions nested within
loop and switch statements, by teaching Scope that a function scope never has a continue/break parent for the purposes of control flow. Remove the hack in block and lambda expressions which worked around this by pretending that such expressions were continue/break scopes. Remove Scope::ControlParent, since it's unused. In passing, teach default statements to recover properly from a missing ';', and add a fixit for same to both default and case labels (the latter already recovered correctly). llvm-svn: 150776
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r--clang/lib/Parse/ParseExpr.cpp1
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp1
-rw-r--r--clang/lib/Parse/ParseStmt.cpp21
3 files changed, 14 insertions, 9 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 642fc2ac650..75510ad440a 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -2290,7 +2290,6 @@ ExprResult Parser::ParseBlockLiteralExpression() {
// allows determining whether a variable reference inside the block is
// within or outside of the block.
ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
- Scope::BreakScope | Scope::ContinueScope |
Scope::DeclScope);
// Inform sema that we are starting a block.
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index d09dba25856..76cc3928664 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -871,7 +871,6 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
// FIXME: Rename BlockScope -> ClosureScope if we decide to continue using
// it.
ParseScope BodyScope(this, Scope::BlockScope | Scope::FnScope |
- Scope::BreakScope | Scope::ContinueScope |
Scope::DeclScope);
Actions.ActOnStartOfLambdaDefinition(Intro, D, getCurScope());
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index 8af4da6a846..c256f7842de 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -596,7 +596,8 @@ StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs, bool MissingCase,
// Nicely diagnose the common error "switch (X) { case 4: }", which is
// not valid.
SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
- Diag(AfterColonLoc, diag::err_label_end_of_compound_statement);
+ Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
+ << FixItHint::CreateInsertion(AfterColonLoc, " ;");
SubStmt = true;
}
@@ -638,16 +639,22 @@ StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) {
ColonLoc = ExpectedLoc;
}
- // Diagnose the common error "switch (X) {... default: }", which is not valid.
- if (Tok.is(tok::r_brace)) {
+ StmtResult SubStmt;
+
+ if (Tok.isNot(tok::r_brace)) {
+ SubStmt = ParseStatement();
+ } else {
+ // Diagnose the common error "switch (X) {... default: }", which is
+ // not valid.
SourceLocation AfterColonLoc = PP.getLocForEndOfToken(ColonLoc);
- Diag(AfterColonLoc, diag::err_label_end_of_compound_statement);
- return StmtError();
+ Diag(AfterColonLoc, diag::err_label_end_of_compound_statement)
+ << FixItHint::CreateInsertion(AfterColonLoc, " ;");
+ SubStmt = true;
}
- StmtResult SubStmt(ParseStatement());
+ // Broken sub-stmt shouldn't prevent forming the case statement properly.
if (SubStmt.isInvalid())
- return StmtError();
+ SubStmt = Actions.ActOnNullStmt(ColonLoc);
return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc,
SubStmt.get(), getCurScope());
OpenPOWER on IntegriCloud