aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-02-15 18:34:13 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-02-15 18:34:13 +0000
commit820b23dc924a4ae7af07d5a75d6b1d781c267d57 (patch)
tree41ebf4f1191d15987c38300b22c8d3d526f28fba
parentb130a54940171a95422a20a07ee8fdfe009806a5 (diff)
When a statement is dropped from the AST because it was invalid, make sure
we don't do the scope checks otherwise we are going to hit assertion checks since a label may not have been actually added. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175281 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/ScopeInfo.h13
-rw-r--r--lib/Parse/ParseStmt.cpp5
-rw-r--r--lib/Sema/SemaStmt.cpp7
-rw-r--r--test/SemaCXX/scope-check.cpp12
4 files changed, 30 insertions, 7 deletions
diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h
index 990bb53c09..2295bf437c 100644
--- a/include/clang/Sema/ScopeInfo.h
+++ b/include/clang/Sema/ScopeInfo.h
@@ -91,6 +91,9 @@ public:
/// \brief Whether this function contains any indirect gotos.
bool HasIndirectGoto;
+ /// \brief Whether a statement was dropped because it was invalid.
+ bool HasDroppedStmt;
+
/// A flag that is set when parsing a method that must call super's
/// implementation, such as \c -dealloc, \c -finalize, or any method marked
/// with \c __attribute__((objc_requires_super)).
@@ -287,9 +290,14 @@ public:
HasIndirectGoto = true;
}
+ void setHasDroppedStmt() {
+ HasDroppedStmt = true;
+ }
+
bool NeedsScopeChecking() const {
- return HasIndirectGoto ||
- (HasBranchProtectedScope && HasBranchIntoScope);
+ return !HasDroppedStmt &&
+ (HasIndirectGoto ||
+ (HasBranchProtectedScope && HasBranchIntoScope));
}
FunctionScopeInfo(DiagnosticsEngine &Diag)
@@ -297,6 +305,7 @@ public:
HasBranchProtectedScope(false),
HasBranchIntoScope(false),
HasIndirectGoto(false),
+ HasDroppedStmt(false),
ObjCShouldCallSuper(false),
ErrorTrap(Diag) { }
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 8b026e859f..4c8bd6fe56 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1042,11 +1042,6 @@ StmtResult Parser::ParseIfStatement(SourceLocation *TrailingElseLoc) {
IfScope.Exit();
- // If the condition was invalid, discard the if statement. We could recover
- // better by replacing it with a valid expr, but don't do that yet.
- if (CondExp.isInvalid() && !CondVar)
- return StmtError();
-
// If the then or else stmt is invalid and the other is valid (and present),
// make turn the invalid one into a null stmt to avoid dropping the other
// part. If both are invalid, return error.
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index fd3ee0d9f5..dcb86b780b 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -406,6 +406,13 @@ StmtResult
Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar,
Stmt *thenStmt, SourceLocation ElseLoc,
Stmt *elseStmt) {
+ // If the condition was invalid, discard the if statement. We could recover
+ // better by replacing it with a valid expr, but don't do that yet.
+ if (!CondVal.get() && !CondVar) {
+ getCurFunction()->setHasDroppedStmt();
+ return StmtError();
+ }
+
ExprResult CondResult(CondVal.release());
VarDecl *ConditionVar = 0;
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index 8fd23f4efe..de276ae3d3 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -274,3 +274,15 @@ namespace test15 {
goto x; // expected-error {{goto into protected scope}}
}
}
+
+namespace test16 {
+Invalid inv; // expected-error {{unknown type name}}
+// Make sure this doesn't assert.
+void fn()
+{
+ int c = 0;
+ if (inv)
+Here: ;
+ goto Here;
+}
+}