value flow: bailout when variable is used in assignment to itself
This commit is contained in:
parent
1fc2c9fe79
commit
75f9111775
|
@ -82,6 +82,24 @@ static const Token * skipValueInConditionalExpression(const Token *tok)
|
|||
return tok;
|
||||
}
|
||||
|
||||
static bool bailoutSelfAssignment(const Token * const tok)
|
||||
{
|
||||
const Token *parent = tok;
|
||||
while (parent) {
|
||||
const Token *op = parent;
|
||||
parent = parent->astParent();
|
||||
|
||||
// Assignment where lhs variable exists in rhs => return true
|
||||
if (parent != NULL &&
|
||||
parent->astOperand2() == op &&
|
||||
parent->astOperand1() != NULL &&
|
||||
parent->str() == "=" &&
|
||||
parent->astOperand1()->str() == tok->str())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLogger, const Settings *settings)
|
||||
{
|
||||
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) {
|
||||
|
@ -152,6 +170,13 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, ErrorLogger *errorLog
|
|||
break;
|
||||
}
|
||||
|
||||
// bailout: variable is used in rhs in assignment to itself
|
||||
if (bailoutSelfAssignment(tok2)) {
|
||||
if (settings->debugwarnings)
|
||||
bailout(tokenlist, errorLogger, tok2, "variable " + tok2->str() + " is used in rhs in assignment to itself");
|
||||
break;
|
||||
}
|
||||
|
||||
// assigned by subfunction?
|
||||
if (bailoutFunctionPar(tok2)) {
|
||||
if (settings->debugwarnings)
|
||||
|
|
|
@ -104,6 +104,14 @@ private:
|
|||
"}";
|
||||
ASSERT_EQUALS(true, testValueOfX(code, 3U, 123));
|
||||
|
||||
// assignment
|
||||
code = "void f(int x) {\n"
|
||||
" x = 2 + x;\n"
|
||||
" if (x == 65);\n"
|
||||
"}";
|
||||
ASSERT_EQUALS(false, testValueOfX(code, 2U, 65));
|
||||
|
||||
|
||||
// guarding by &&
|
||||
code = "void f(int x) {\n"
|
||||
" if (!x || \n" // <- x can be 0
|
||||
|
|
Loading…
Reference in New Issue