From b8f45a5c65938fda9b684a72160eff8100218d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 25 Dec 2020 08:43:14 +0100 Subject: [PATCH] Replace and fix findBreakScope with findNextTokenFromBreak --- lib/astutils.cpp | 24 ++++++++++++++++-------- lib/astutils.h | 5 +++-- lib/checkvaarg.cpp | 5 ++--- lib/forwardanalyzer.cpp | 6 +++--- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 277d556a0..6c775e0a0 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -494,10 +494,18 @@ const Token* getCondTokFromEnd(const Token* endBlock) return getCondTokFromEndImpl(endBlock); } -const Scope *findBreakScope(const Scope *s) { - while (s && !s->isLoopScope() && s->type != Scope::ScopeType::eSwitch) - s = s->nestedIn; - return s; +const Token *findNextTokenFromBreak(const Token *breakToken) +{ + const Scope *scope = breakToken->scope(); + while (scope) { + if (scope->isLoopScope() || scope->type == Scope::ScopeType::eSwitch) { + if (scope->type == Scope::ScopeType::eDo && Token::simpleMatch(scope->bodyEnd, "} while (")) + return scope->bodyEnd->linkAt(2)->next(); + return scope->bodyEnd; + } + scope = scope->nestedIn; + } + return nullptr; } bool extractForLoopValues(const Token *forToken, @@ -2513,10 +2521,10 @@ FwdAnalysis::Result FwdAnalysis::check(const Token* expr, const Token* startToke // Break => continue checking in outer scope while (mWhat!=What::ValueFlow && result.type == FwdAnalysis::Result::Type::BREAK) { - const Scope *breakScope = findBreakScope(result.token->scope()); - if (!breakScope) - break; - result = checkRecursive(expr, breakScope->bodyEnd->next(), endToken, exprVarIds, local, false); + const Token *scopeEndToken = findNextTokenFromBreak(result.token); + if (!scopeEndToken) + break; + result = checkRecursive(expr, scopeEndToken->next(), endToken, exprVarIds, local, false); } return result; diff --git a/lib/astutils.h b/lib/astutils.h index facedaa3e..a4f6d83a9 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -115,8 +115,9 @@ const Token* getCondTok(const Token* tok); Token* getCondTokFromEnd(Token* endBlock); const Token* getCondTokFromEnd(const Token* endBlock); -/// For a "break", locate the outer loop/switch scope that is finished -const Scope *findBreakScope(const Scope *scope); +/// For a "break" token, locate the next token to execute. The token will +/// be either a "}" or a ";". +const Token *findNextTokenFromBreak(const Token *breakToken); /** * Extract for loop values: loopvar varid, init value, step value, last value (inclusive) diff --git a/lib/checkvaarg.cpp b/lib/checkvaarg.cpp index e37bd5414..74151be8e 100644 --- a/lib/checkvaarg.cpp +++ b/lib/checkvaarg.cpp @@ -139,10 +139,9 @@ void CheckVaarg::va_list_usage() } else if (Token::Match(tok, "throw|return")) exitOnEndOfStatement = true; else if (tok->str() == "break") { - const Scope *breakScope = findBreakScope(tok->scope()); - if (!breakScope) + tok = findNextTokenFromBreak(tok); + if (!tok) return; - tok = breakScope->bodyEnd; } else if (tok->str() == "goto" || (mTokenizer->isCPP() && tok->str() == "try")) { open = false; break; diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index da6e3e271..c2f29b92d 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -297,10 +297,10 @@ struct ForwardTraversal { if (!tok) return Progress::Break; } else if (tok->str() == "break") { - const Scope* scope = findBreakScope(tok->scope()); - if (!scope) + const Token *scopeEndToken = findNextTokenFromBreak(tok); + if (!scopeEndToken) return Progress::Break; - tok = skipTo(tok, scope->bodyEnd, end); + tok = skipTo(tok, scopeEndToken, end); if (!analyzer->lowerToPossible()) return Progress::Break; // TODO: Don't break, instead move to the outer scope