diff --git a/clang/lib/Sema/JumpDiagnostics.cpp b/clang/lib/Sema/JumpDiagnostics.cpp --- a/clang/lib/Sema/JumpDiagnostics.cpp +++ b/clang/lib/Sema/JumpDiagnostics.cpp @@ -73,7 +73,7 @@ SmallVector IndirectJumps; SmallVector IndirectJumpTargets; - SmallVector MustTailStmts; + SmallVector MustTailStmts; public: JumpScopeChecker(Stmt *Body, Sema &S); @@ -97,6 +97,7 @@ const Attr *GetMustTailAttr(AttributedStmt *AS); unsigned GetDeepestCommonScope(unsigned A, unsigned B); + void RecordJumpScope(Stmt *S, unsigned Scope, SmallVectorImpl *Jumps); }; } // end anonymous namespace @@ -325,21 +326,19 @@ return; } - case Stmt::IndirectGotoStmtClass: + case Stmt::IndirectGotoStmtClass: { // "goto *&&lbl;" is a special case which we treat as equivalent // to a normal goto. In addition, we don't calculate scope in the // operand (to avoid recording the address-of-label use), which // works only because of the restricted set of expressions which // we detect as constant targets. - if (cast(S)->getConstantTarget()) { - LabelAndGotoScopes[S] = ParentScope; - Jumps.push_back(S); - return; - } - - LabelAndGotoScopes[S] = ParentScope; - IndirectJumps.push_back(S); + bool isConst = cast(S)->getConstantTarget(); + if (isConst) + RecordJumpScope(S, ParentScope, &Jumps); + else + RecordJumpScope(S, ParentScope, &IndirectJumps); break; + } case Stmt::SwitchStmtClass: // Evaluate the C++17 init stmt and condition variable @@ -352,17 +351,18 @@ BuildScopeInformation(Var, ParentScope); ++StmtsToSkip; } - [[fallthrough]]; + RecordJumpScope(S, ParentScope, &Jumps); + break; case Stmt::GotoStmtClass: - case Stmt::GCCAsmStmtClass: - if (auto *GS = dyn_cast(S)) - if (!GS->isAsmGoto()) - break; // Remember both what scope a goto is in as well as the fact that we have // it. This makes the second scan not have to walk the AST again. - LabelAndGotoScopes[S] = ParentScope; - Jumps.push_back(S); + RecordJumpScope(S, ParentScope, &Jumps); + break; + + case Stmt::GCCAsmStmtClass: + if (cast(S)->isAsmGoto()) + RecordJumpScope(S, ParentScope, &Jumps); break; case Stmt::IfStmtClass: { @@ -584,14 +584,10 @@ LabelAndGotoScopes[S] = ParentScope; break; - case Stmt::AttributedStmtClass: { - AttributedStmt *AS = cast(S); - if (GetMustTailAttr(AS)) { - LabelAndGotoScopes[AS] = ParentScope; - MustTailStmts.push_back(AS); - } + case Stmt::AttributedStmtClass: + if (GetMustTailAttr(cast(S))) + RecordJumpScope(S, ParentScope, &MustTailStmts); break; - } default: if (auto *ED = dyn_cast(S)) { @@ -986,7 +982,7 @@ } void JumpScopeChecker::VerifyMustTailStmts() { - for (AttributedStmt *AS : MustTailStmts) { + for (Stmt *AS : MustTailStmts) { for (unsigned I = LabelAndGotoScopes[AS]; I; I = Scopes[I].ParentScope) { if (Scopes[I].OutDiag) { S.Diag(AS->getBeginLoc(), diag::err_musttail_scope); @@ -1003,6 +999,12 @@ return Iter != Attrs.end() ? *Iter : nullptr; } +void JumpScopeChecker::RecordJumpScope(Stmt *S, unsigned Scope, + SmallVectorImpl *Jumps) { + LabelAndGotoScopes[S] = Scope; + Jumps->push_back(S); +} + void Sema::DiagnoseInvalidJumps(Stmt *Body) { (void)JumpScopeChecker(Body, *this); }