Fix issue 9235: new crash in astutils isVariableChanged from endless recursion (#2040)
This commit is contained in:
parent
b049fd9303
commit
ee28a45db4
|
@ -968,10 +968,12 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings,
|
||||||
return arg && !arg->isConst() && arg->isReference();
|
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))
|
if (!precedes(start, end))
|
||||||
return false;
|
return false;
|
||||||
|
if (depth < 0)
|
||||||
|
return true;
|
||||||
for (const Token *tok = start; tok != end; tok = tok->next()) {
|
for (const Token *tok = start; tok != end; tok = tok->next()) {
|
||||||
if (tok->varId() != varid) {
|
if (tok->varId() != varid) {
|
||||||
if (globalvar && Token::Match(tok, "%name% ("))
|
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
|
// Check if assigning to a non-const lvalue
|
||||||
const Variable * var = getLHSVariable(tok2->astParent());
|
const Variable * var = getLHSVariable(tok2->astParent());
|
||||||
if (var && var->isReference() && !var->isConst() && var->nameToken() && var->nameToken()->next() == 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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,7 +1052,7 @@ bool isVariableChanged(const Token *start, const Token *end, const nonneg int va
|
||||||
const Variable * loopVar = varTok->variable();
|
const Variable * loopVar = varTok->variable();
|
||||||
if (!loopVar)
|
if (!loopVar)
|
||||||
continue;
|
continue;
|
||||||
if (!loopVar->isConst() && loopVar->isReference() && isVariableChanged(loopVar, settings, cpp))
|
if (!loopVar->isConst() && loopVar->isReference() && isVariableChanged(loopVar, settings, cpp, depth - 1))
|
||||||
return true;
|
return true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1058,7 +1060,7 @@ bool isVariableChanged(const Token *start, const Token *end, const nonneg int va
|
||||||
return false;
|
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)
|
if (!var)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1069,7 +1071,7 @@ bool isVariableChanged(const Variable * var, const Settings *settings, bool cpp)
|
||||||
return false;
|
return false;
|
||||||
if (Token::Match(start, "; %varid% =", var->declarationId()))
|
if (Token::Match(start, "; %varid% =", var->declarationId()))
|
||||||
start = start->tokAt(2);
|
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)
|
int numberOfArguments(const Token *start)
|
||||||
|
|
|
@ -133,9 +133,9 @@ bool isVariableChangedByFunctionCall(const Token *tok, nonneg int varid, const S
|
||||||
bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, bool *inconclusive);
|
bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, bool *inconclusive);
|
||||||
|
|
||||||
/** Is variable changed in block of code? */
|
/** 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);
|
bool isAliased(const Variable *var);
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,10 @@ private:
|
||||||
" int b;\n"
|
" int b;\n"
|
||||||
" if (b) { (int)((INTOF(8))result >> b); }\n"
|
" if (b) { (int)((INTOF(8))result >> b); }\n"
|
||||||
"}", "if", "}");
|
"}", "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) {
|
bool isVariableChangedByFunctionCall(const char code[], const char pattern[], bool *inconclusive) {
|
||||||
|
|
Loading…
Reference in New Issue