Refactoring; Added findBreakScope and Scope::isLoopScope()
This commit is contained in:
parent
9d57b832b8
commit
8bd783f820
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
*/
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ||
|
||||
|
|
Loading…
Reference in New Issue