Refactoring; Added findBreakScope and Scope::isLoopScope()

This commit is contained in:
Daniel Marjamäki 2020-12-24 22:58:19 +01:00
parent 9d57b832b8
commit 8bd783f820
8 changed files with 26 additions and 23 deletions

View File

@ -494,6 +494,12 @@ 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;
}
bool extractForLoopValues(const Token *forToken,
nonneg int * const varid,
bool * const knownInitValue,
@ -2240,8 +2246,7 @@ struct FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const
if (tok->scope() == expr->scope())
mValueFlowKnown = false;
Scope::ScopeType scopeType = tok->scope()->type;
if (scopeType == Scope::eWhile || scopeType == Scope::eFor || scopeType == Scope::eDo) {
if (tok->scope()->isLoopScope()) {
// check condition
const Token *conditionStart = nullptr;
const Token *conditionEnd = nullptr;
@ -2508,12 +2513,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 *s = result.token->scope();
while (s->type == Scope::eIf)
s = s->nestedIn;
if (s->type != Scope::eSwitch && s->type != Scope::eWhile && s->type != Scope::eFor)
break;
result = checkRecursive(expr, s->bodyEnd->next(), endToken, exprVarIds, local, false);
const Scope *breakScope = findBreakScope(result.token->scope());
if (!breakScope)
break;
result = checkRecursive(expr, breakScope->bodyEnd->next(), endToken, exprVarIds, local, false);
}
return result;

View File

@ -31,6 +31,7 @@
#include "utils.h"
class Library;
class Scope;
class Settings;
class Token;
class Variable;
@ -114,6 +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);
/**
* Extract for loop values: loopvar varid, init value, step value, last value (inclusive)
*/

View File

@ -369,7 +369,7 @@ void CheckBool::pointerArithBool()
const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
for (const Scope &scope : symbolDatabase->scopeList) {
if (scope.type != Scope::eIf && scope.type != Scope::eWhile && scope.type != Scope::eDo && scope.type != Scope::eFor)
if (scope.type != Scope::eIf && !scope.isLoopScope())
continue;
const Token* tok = scope.classDef->next()->astOperand2();
if (scope.type == Scope::eFor) {

View File

@ -981,7 +981,7 @@ void CheckOther::checkVariableScope()
bool CheckOther::checkInnerScope(const Token *tok, const Variable* var, bool& used)
{
const Scope* scope = tok->next()->scope();
bool loopVariable = scope->type == Scope::eFor || scope->type == Scope::eWhile || scope->type == Scope::eDo;
bool loopVariable = scope->isLoopScope();
bool noContinue = true;
const Token* forHeadEnd = nullptr;
const Token* end = tok->link();

View File

@ -1039,7 +1039,7 @@ void CheckStl::stlOutOfBounds()
for (const Scope &scope : symbolDatabase->scopeList) {
const Token* tok = scope.classDef;
// only interested in conditions
if ((scope.type != Scope::eFor && scope.type != Scope::eWhile && scope.type != Scope::eIf && scope.type != Scope::eDo) || !tok)
if ((!scope.isLoopScope() && scope.type != Scope::eIf) || !tok)
continue;
const Token *condition = nullptr;
@ -2001,7 +2001,7 @@ void CheckStl::checkDereferenceInvalidIterator()
// Iterate over "if", "while", and "for" conditions where there may
// be an iterator that is dereferenced before being checked for validity.
for (const Scope &scope : mTokenizer->getSymbolDatabase()->scopeList) {
if (!(scope.type == Scope::eIf || scope.type == Scope::eDo || scope.type == Scope::eWhile || scope.type == Scope::eFor))
if (!(scope.type == Scope::eIf || scope.isLoopScope()))
continue;
const Token* const tok = scope.classDef;

View File

@ -139,12 +139,10 @@ void CheckVaarg::va_list_usage()
} else if (Token::Match(tok, "throw|return"))
exitOnEndOfStatement = true;
else if (tok->str() == "break") {
const Scope* scope = tok->scope();
while (scope->nestedIn && scope->type != Scope::eFor && scope->type != Scope::eWhile && scope->type != Scope::eDo && scope->type != Scope::eSwitch)
scope = scope->nestedIn;
tok = scope->bodyEnd;
if (!tok)
const Scope *breakScope = findBreakScope(tok->scope());
if (!breakScope)
return;
tok = breakScope->bodyEnd;
} else if (tok->str() == "goto" || (mTokenizer->isCPP() && tok->str() == "try")) {
open = false;
break;

View File

@ -505,12 +505,6 @@ struct ForwardTraversal {
return nullptr;
}
static const Scope* findBreakScope(const Scope* scope) {
while (scope && scope->type != Scope::eWhile && scope->type != Scope::eFor && scope->type != Scope::eSwitch)
scope = scope->nestedIn;
return scope;
}
static Token* skipTo(Token* tok, const Token* dest, const Token* end = nullptr) {
if (end && dest->index() > end->index())
return nullptr;

View File

@ -1067,6 +1067,10 @@ public:
return type != eClass && type != eStruct && type != eUnion && type != eGlobal && type != eNamespace && type != eEnum;
}
bool isLoopScope() const {
return type == Scope::ScopeType::eFor || type == Scope::ScopeType::eWhile || type == Scope::ScopeType::eDo;
}
bool isLocal() const {
return (type == eIf || type == eElse ||
type == eFor || type == eWhile || type == eDo ||