Fixed #9649 (False positive: uninitialized struct member)

This commit is contained in:
Daniel Marjamäki 2020-05-07 22:25:08 +02:00
parent c04a73f6d8
commit 4779cb124e
2 changed files with 21 additions and 10 deletions

View File

@ -435,20 +435,18 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
const Token *condition = tok->next()->astOperand2(); const Token *condition = tok->next()->astOperand2();
const Token *lhs = condition->astOperand1(); const Token *lhs = condition->astOperand1();
const Token *rhs = condition->astOperand2(); const Token *rhs = condition->astOperand2();
const Token *vartok = rhs && rhs->isNumber() ? lhs : rhs; const Token *vartok = (lhs && lhs->hasKnownIntValue()) ? rhs : lhs;
const Token *numtok = rhs && rhs->isNumber() ? rhs : lhs; const Token *numtok = (lhs == vartok) ? rhs : lhs;
while (Token::simpleMatch(vartok, ".")) while (Token::simpleMatch(vartok, "."))
vartok = vartok->astOperand2(); vartok = vartok->astOperand2();
if (vartok && vartok->varId() && numtok) { if (vartok && vartok->varId() && numtok && numtok->hasKnownIntValue()) {
const std::map<int,VariableValue>::const_iterator it = variableValue.find(vartok->varId()); const std::map<int,VariableValue>::const_iterator it = variableValue.find(vartok->varId());
if (it != variableValue.end() && it->second != MathLib::toLongNumber(numtok->str())) if (it != variableValue.end() && it->second != numtok->getKnownIntValue())
return true; // this scope is not fully analysed => return true return true; // this scope is not fully analysed => return true
else { condVarId = vartok->varId();
condVarId = vartok->varId(); condVarValue = VariableValue(numtok->getKnownIntValue());
condVarValue = VariableValue(MathLib::toLongNumber(numtok->str())); if (condition->str() == "!=")
if (condition->str() == "!=") condVarValue = !condVarValue;
condVarValue = !condVarValue;
}
} }
} }

View File

@ -2523,6 +2523,19 @@ private:
"}"); "}");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
checkUninitVar("enum t_err { ERR_NONE, ERR_BAD_ARGS };\n" // #9649
"struct box_t { int value; };\n"
"int init_box(box_t *p, int v);\n"
"\n"
"void foo(int ret) {\n"
" box_t box2;\n"
" if (ret == ERR_NONE)\n"
" ret = init_box(&box2, 20);\n"
" if (ret == ERR_NONE)\n"
" z = x + box2.value;\n"
"}");
ASSERT_EQUALS("", errout.str());
checkUninitVar("void f(int x) {\n" checkUninitVar("void f(int x) {\n"
" int value;\n" " int value;\n"
" if (x == 32)\n" " if (x == 32)\n"