Fixed #4885 (FP Uninitialized variable when using comma)
This commit is contained in:
parent
6997d38881
commit
ba23b65179
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue