diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-02-15 18:34:13 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-02-15 18:34:13 +0000 |
commit | 820b23dc924a4ae7af07d5a75d6b1d781c267d57 (patch) | |
tree | 41ebf4f1191d15987c38300b22c8d3d526f28fba | |
parent | b130a54940171a95422a20a07ee8fdfe009806a5 (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.h | 13 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 7 | ||||
-rw-r--r-- | test/SemaCXX/scope-check.cpp | 12 |
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; +} +} |