Fixed #9251 (False positive: unininitialized variable (multi variables))
This commit is contained in:
parent
24431419f4
commit
ce53931d00
|
@ -1908,25 +1908,22 @@ static void valueFlowAST(Token *tok, nonneg int varid, const ValueFlow::Value &v
|
||||||
}
|
}
|
||||||
|
|
||||||
/** if known variable is changed in loop body, change it to a possible value */
|
/** if known variable is changed in loop body, change it to a possible value */
|
||||||
static void handleKnownValuesInLoop(const Token *startToken,
|
static bool handleKnownValuesInLoop(const Token *startToken,
|
||||||
const Token *endToken,
|
const Token *endToken,
|
||||||
std::list<ValueFlow::Value> *values,
|
std::list<ValueFlow::Value> *values,
|
||||||
nonneg int varid,
|
nonneg int varid,
|
||||||
bool globalvar,
|
bool globalvar,
|
||||||
const Settings *settings)
|
const Settings *settings)
|
||||||
{
|
{
|
||||||
bool isChanged = false;
|
const bool isChanged = isVariableChanged(startToken, endToken, varid, globalvar, settings, true);
|
||||||
|
if (!isChanged)
|
||||||
|
return false;
|
||||||
for (std::list<ValueFlow::Value>::iterator it = values->begin(); it != values->end(); ++it) {
|
for (std::list<ValueFlow::Value>::iterator it = values->begin(); it != values->end(); ++it) {
|
||||||
if (it->isKnown()) {
|
if (it->isKnown()) {
|
||||||
if (!isChanged) {
|
|
||||||
if (!isVariableChanged(startToken, endToken, varid, globalvar, settings, true))
|
|
||||||
break;
|
|
||||||
isChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
it->setPossible();
|
it->setPossible();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return isChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool evalAssignment(ValueFlow::Value &lhsValue, const std::string &assign, const ValueFlow::Value &rhsValue)
|
static bool evalAssignment(ValueFlow::Value &lhsValue, const std::string &assign, const ValueFlow::Value &rhsValue)
|
||||||
|
@ -2113,8 +2110,10 @@ static bool valueFlowForward(Token * const startToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
// if known variable is changed in loop body, change it to a possible value..
|
// if known variable is changed in loop body, change it to a possible value..
|
||||||
if (Token::Match(tok2, "for|while"))
|
if (Token::Match(tok2, "for|while")) {
|
||||||
handleKnownValuesInLoop(tok2, tok2->linkAt(1)->linkAt(1), &values, varid, var->isGlobal(), settings);
|
if (handleKnownValuesInLoop(tok2, tok2->linkAt(1)->linkAt(1), &values, varid, var->isGlobal(), settings))
|
||||||
|
number_of_if++;
|
||||||
|
}
|
||||||
|
|
||||||
// Set values in condition
|
// Set values in condition
|
||||||
for (Token* tok3 = tok2->tokAt(2); tok3 != tok2->next()->link(); tok3 = tok3->next()) {
|
for (Token* tok3 = tok2->tokAt(2); tok3 != tok2->next()->link(); tok3 = tok3->next()) {
|
||||||
|
|
|
@ -1912,6 +1912,21 @@ private:
|
||||||
"}\n";
|
"}\n";
|
||||||
ASSERT_EQUALS(true, testValueOfX(code, 9U, 0)); // x can be 0 at line 9
|
ASSERT_EQUALS(true, testValueOfX(code, 9U, 0)); // x can be 0 at line 9
|
||||||
|
|
||||||
|
code = "void f(const int *buf) {\n"
|
||||||
|
" int x = 111;\n"
|
||||||
|
" bool found = false;\n"
|
||||||
|
" for (int i = 0; i < 10; i++) {\n"
|
||||||
|
" if (buf[i] == 123) {\n"
|
||||||
|
" x = i;\n"
|
||||||
|
" found = true;\n"
|
||||||
|
" break;\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" if (found)\n"
|
||||||
|
" a = x;\n" // <- x can't be 111
|
||||||
|
"}\n";
|
||||||
|
ASSERT_EQUALS(false, testValueOfX(code, 12U, 111)); // x can not be 111 at line 9
|
||||||
|
|
||||||
code = "void f(const int *buf) {\n"
|
code = "void f(const int *buf) {\n"
|
||||||
" int x = 0;\n"
|
" int x = 0;\n"
|
||||||
" for (int i = 0; i < 10; i++) {\n"
|
" for (int i = 0; i < 10; i++) {\n"
|
||||||
|
|
Loading…
Reference in New Issue