diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 19c6e7fa4..a9b3e44ec 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -968,10 +968,12 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, return arg && !arg->isConst() && arg->isReference(); } -bool isVariableChanged(const Token *start, const Token *end, const nonneg int varid, bool globalvar, const Settings *settings, bool cpp) +bool isVariableChanged(const Token *start, const Token *end, const nonneg int varid, bool globalvar, const Settings *settings, bool cpp, int depth) { if (!precedes(start, end)) return false; + if (depth < 0) + return true; for (const Token *tok = start; tok != end; tok = tok->next()) { if (tok->varId() != varid) { if (globalvar && Token::Match(tok, "%name% (")) @@ -994,7 +996,7 @@ bool isVariableChanged(const Token *start, const Token *end, const nonneg int va // Check if assigning to a non-const lvalue const Variable * var = getLHSVariable(tok2->astParent()); if (var && var->isReference() && !var->isConst() && var->nameToken() && var->nameToken()->next() == tok2->astParent()) { - if (!var->isLocal() || isVariableChanged(var, settings, cpp)) + if (!var->isLocal() || isVariableChanged(var, settings, cpp, depth - 1)) return true; } } @@ -1050,7 +1052,7 @@ bool isVariableChanged(const Token *start, const Token *end, const nonneg int va const Variable * loopVar = varTok->variable(); if (!loopVar) continue; - if (!loopVar->isConst() && loopVar->isReference() && isVariableChanged(loopVar, settings, cpp)) + if (!loopVar->isConst() && loopVar->isReference() && isVariableChanged(loopVar, settings, cpp, depth - 1)) return true; continue; } @@ -1058,7 +1060,7 @@ bool isVariableChanged(const Token *start, const Token *end, const nonneg int va return false; } -bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp) +bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp, int depth) { if (!var) return false; @@ -1069,7 +1071,7 @@ bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp) return false; if (Token::Match(start, "; %varid% =", var->declarationId())) start = start->tokAt(2); - return isVariableChanged(start->next(), var->scope()->bodyEnd, var->declarationId(), var->isGlobal(), settings, cpp); + return isVariableChanged(start->next(), var->scope()->bodyEnd, var->declarationId(), var->isGlobal(), settings, cpp, depth); } int numberOfArguments(const Token *start) diff --git a/lib/astutils.h b/lib/astutils.h index 0fc6124ab..eb9200f1f 100644 --- a/lib/astutils.h +++ b/lib/astutils.h @@ -133,9 +133,9 @@ bool isVariableChangedByFunctionCall(const Token *tok, nonneg int varid, const S bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, bool *inconclusive); /** Is variable changed in block of code? */ -bool isVariableChanged(const Token *start, const Token *end, const nonneg int varid, bool globalvar, const Settings *settings, bool cpp); +bool isVariableChanged(const Token *start, const Token *end, const nonneg int varid, bool globalvar, const Settings *settings, bool cpp, int depth = 20); -bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp); +bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp, int depth = 20); bool isAliased(const Variable *var); diff --git a/test/testastutils.cpp b/test/testastutils.cpp index 49e66a542..d6f899e31 100644 --- a/test/testastutils.cpp +++ b/test/testastutils.cpp @@ -147,6 +147,10 @@ private: " int b;\n" " if (b) { (int)((INTOF(8))result >> b); }\n" "}", "if", "}"); + // #9235 + ASSERT_EQUALS(true, isVariableChanged("void f() {\n" + " int &a = a;\n" + "}\n", "= a", "}")); } bool isVariableChangedByFunctionCall(const char code[], const char pattern[], bool *inconclusive) {