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 (tok->varId() == var.varId()) {
|
||||||
if (!membervar.empty()) {
|
if (!membervar.empty()) {
|
||||||
if (isMemberVariableAssignment(tok, membervar)) {
|
if (isMemberVariableAssignment(tok, membervar)) {
|
||||||
bool rhs = false;
|
checkRhs(tok, var, membervar);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1419,14 +1412,8 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
|
||||||
uninitvarError(tok, tok->str());
|
uninitvarError(tok, tok->str());
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (tok->strAt(1) == "=") {
|
if (tok->strAt(1) == "=")
|
||||||
for (const Token *tok2 = tok->next(); tok2 && tok2->str() != ";"; tok2 = tok2->next()) {
|
checkRhs(tok, var, "");
|
||||||
if (tok2->varId() == tok->varId() && isVariableUsage(tok2, var.isPointer(), _tokenizer->isCPP())) {
|
|
||||||
uninitvarError(tok, tok->str());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// assume that variable is assigned
|
// assume that variable is assigned
|
||||||
return true;
|
return true;
|
||||||
|
@ -1537,6 +1524,31 @@ bool CheckUninitVar::checkLoopBody(const Token *tok, const Variable& var, const
|
||||||
return false;
|
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)
|
bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool cpp)
|
||||||
{
|
{
|
||||||
if (vartok->previous()->str() == "return")
|
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 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 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);
|
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);
|
static bool isVariableUsage(const Token *vartok, bool ispointer, bool cpp);
|
||||||
bool isMemberVariableAssignment(const Token *tok, const std::string &membervar) const;
|
bool isMemberVariableAssignment(const Token *tok, const std::string &membervar) const;
|
||||||
bool isMemberVariableUsage(const Token *tok, bool isPointer, 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());
|
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
|
// using uninit var in condition
|
||||||
checkUninitVar2("void f(void) {\n"
|
checkUninitVar2("void f(void) {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
|
|
Loading…
Reference in New Issue