From: Argyrios Kyrtzidis Date: Fri, 15 Feb 2013 18:34:13 +0000 (+0000) Subject: When a statement is dropped from the AST because it was invalid, make sure X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e6e422b1ee4f6a6530a54abc8f31afd2be2340c8;p=platform%2Fupstream%2Fllvm.git 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. llvm-svn: 175281 --- diff --git a/clang/include/clang/Sema/ScopeInfo.h b/clang/include/clang/Sema/ScopeInfo.h index 990bb53..2295bf4 100644 --- a/clang/include/clang/Sema/ScopeInfo.h +++ b/clang/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/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 8b026e8..4c8bd6f 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/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/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index fd3ee0d..dcb86b7 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/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/clang/test/SemaCXX/scope-check.cpp b/clang/test/SemaCXX/scope-check.cpp index 8fd23f4..de276ae 100644 --- a/clang/test/SemaCXX/scope-check.cpp +++ b/clang/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; +} +}