diff options
Diffstat (limited to 'clang/lib/Sema/JumpDiagnostics.cpp')
| -rw-r--r-- | clang/lib/Sema/JumpDiagnostics.cpp | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp index 1f5d682bba1..27bca15b4c1 100644 --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -32,6 +32,10 @@ namespace { class JumpScopeChecker { Sema &S; + /// Permissive - True when recovering from errors, in which case precautions + /// are taken to handle incomplete scope information. + const bool Permissive; + /// GotoScope - This is a record that we use to keep track of all of the /// scopes that are introduced by VLAs and other things that scope jumps like /// gotos. This scope tree has nothing to do with the source scope tree, @@ -85,8 +89,10 @@ private: }; } // end anonymous namespace +#define CHECK_PERMISSIVE(x) (assert(Permissive || !(x)), (Permissive && (x))) -JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s) : S(s) { +JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s) + : S(s), Permissive(s.hasAnyUnrecoverableErrorsInThisFunction()) { // Add a scope entry for function scope. Scopes.push_back(GotoScope(~0U, ~0U, ~0U, SourceLocation())); @@ -503,7 +509,8 @@ void JumpScopeChecker::VerifyJumps() { SwitchStmt *SS = cast<SwitchStmt>(Jump); for (SwitchCase *SC = SS->getSwitchCaseList(); SC; SC = SC->getNextSwitchCase()) { - assert(LabelAndGotoScopes.count(SC) && "Case not visited?"); + if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(SC))) + continue; SourceLocation Loc; if (CaseStmt *CS = dyn_cast<CaseStmt>(SC)) Loc = CS->getLocStart(); @@ -557,8 +564,8 @@ void JumpScopeChecker::VerifyIndirectJumps() { for (SmallVectorImpl<IndirectGotoStmt*>::iterator I = IndirectJumps.begin(), E = IndirectJumps.end(); I != E; ++I) { IndirectGotoStmt *IG = *I; - assert(LabelAndGotoScopes.count(IG) && - "indirect jump didn't get added to scopes?"); + if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(IG))) + continue; unsigned IGScope = LabelAndGotoScopes[IG]; IndirectGotoStmt *&Entry = JumpScopesMap[IGScope]; if (!Entry) Entry = IG; @@ -577,8 +584,8 @@ void JumpScopeChecker::VerifyIndirectJumps() { I = IndirectJumpTargets.begin(), E = IndirectJumpTargets.end(); I != E; ++I) { LabelDecl *TheLabel = *I; - assert(LabelAndGotoScopes.count(TheLabel->getStmt()) && - "Referenced label didn't get added to scopes?"); + if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(TheLabel->getStmt()))) + continue; unsigned LabelScope = LabelAndGotoScopes[TheLabel->getStmt()]; LabelDecl *&Target = TargetScopes[LabelScope]; if (!Target) Target = TheLabel; @@ -683,7 +690,8 @@ static void DiagnoseIndirectJumpStmt(Sema &S, IndirectGotoStmt *Jump, /// Produce note diagnostics for a jump into a protected scope. void JumpScopeChecker::NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes) { - assert(!ToScopes.empty()); + if (CHECK_PERMISSIVE(ToScopes.empty())) + return; for (unsigned I = 0, E = ToScopes.size(); I != E; ++I) if (Scopes[ToScopes[I]].InDiag) S.Diag(Scopes[ToScopes[I]].Loc, Scopes[ToScopes[I]].InDiag); @@ -694,7 +702,8 @@ void JumpScopeChecker::DiagnoseIndirectJump(IndirectGotoStmt *Jump, unsigned JumpScope, LabelDecl *Target, unsigned TargetScope) { - assert(JumpScope != TargetScope); + if (CHECK_PERMISSIVE(JumpScope == TargetScope)) + return; unsigned Common = GetDeepestCommonScope(JumpScope, TargetScope); bool Diagnosed = false; @@ -731,10 +740,12 @@ void JumpScopeChecker::DiagnoseIndirectJump(IndirectGotoStmt *Jump, void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc, unsigned JumpDiagError, unsigned JumpDiagWarning, unsigned JumpDiagCXX98Compat) { - assert(LabelAndGotoScopes.count(From) && "Jump didn't get added to scopes?"); - unsigned FromScope = LabelAndGotoScopes[From]; + if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(From))) + return; + if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(To))) + return; - assert(LabelAndGotoScopes.count(To) && "Jump didn't get added to scopes?"); + unsigned FromScope = LabelAndGotoScopes[From]; unsigned ToScope = LabelAndGotoScopes[To]; // Common case: exactly the same scope, which is fine. |

