Fixed #4885 (FP Uninitialized variable when using comma)

This commit is contained in:
Daniel Marjamäki 2013-06-29 09:33:51 +02:00
parent 6997d38881
commit ba23b65179
3 changed files with 35 additions and 16 deletions

View File

@ -1396,14 +1396,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
if (tok->varId() == var.varId()) {
if (!membervar.empty()) {
if (isMemberVariableAssignment(tok, membervar)) {
bool rhs = false;
for (const Token *tok2 = tok; tok2 && tok2->str() != ";"; tok2 = tok2->next()) {
if (tok2->str() == "=")
rhs = true;
else if (rhs && tok2->varId() == var.varId() && isMemberVariableUsage(tok2, var.isPointer(), membervar))
uninitStructMemberError(tok2, tok2->str() + "." + membervar);
}
checkRhs(tok, var, membervar);
return true;
}
@ -1419,14 +1412,8 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
uninitvarError(tok, tok->str());
else {
if (tok->strAt(1) == "=") {
for (const Token *tok2 = tok->next(); tok2 && tok2->str() != ";"; tok2 = tok2->next()) {
if (tok2->varId() == tok->varId() && isVariableUsage(tok2, var.isPointer(), _tokenizer->isCPP())) {
uninitvarError(tok, tok->str());
break;
}
}
}
if (tok->strAt(1) == "=")
checkRhs(tok, var, "");
// assume that variable is assigned
return true;
@ -1537,6 +1524,31 @@ bool CheckUninitVar::checkLoopBody(const Token *tok, const Variable& var, const
return false;
}
void CheckUninitVar::checkRhs(const Token *tok, const Variable &var, const std::string &membervar)
{
bool rhs = false;
unsigned int indent = 0;
while (tok = tok->next()) {
if (tok->str() == "=")
rhs = true;
if (rhs && tok->varId() == var.varId()) {
if (membervar.empty() && isVariableUsage(tok, var.isPointer(), _tokenizer->isCPP()))
uninitvarError(tok, tok->str());
else if (!membervar.empty() && isMemberVariableUsage(tok, var.isPointer(), membervar))
uninitStructMemberError(tok, tok->str() + "." + membervar);
} else if (tok->str() == ";" || (indent==0 && tok->str() == ","))
break;
else if (tok->str() == "(")
++indent;
else if (tok->str() == ")") {
if (indent == 0)
break;
--indent;
}
}
}
bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool cpp)
{
if (vartok->previous()->str() == "return")

View File

@ -60,6 +60,7 @@ public:
bool checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const std::string &membervar);
bool checkIfForWhileHead(const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, const std::string &membervar);
bool checkLoopBody(const Token *tok, const Variable& var, const std::string &membervar, const bool suppressErrors);
void checkRhs(const Token *tok, const Variable &var, const std::string &membervar);
static bool isVariableUsage(const Token *vartok, bool ispointer, bool cpp);
bool isMemberVariableAssignment(const Token *tok, const std::string &membervar) const;
bool isMemberVariableUsage(const Token *tok, bool isPointer, const std::string &membervar) const;

View File

@ -2035,6 +2035,12 @@ private:
"}");
ASSERT_EQUALS("", errout.str());
checkUninitVar2("void f() {\n"
" int i;\n"
" i=f(), i!=2;\n"
"}");
ASSERT_EQUALS("", errout.str());
// using uninit var in condition
checkUninitVar2("void f(void) {\n"
" int x;\n"