Uninitialized variables: check more variables
This commit is contained in:
parent
f48edb63a3
commit
8eb067358c
|
@ -1049,16 +1049,31 @@ void CheckUninitVar::check()
|
||||||
// only check functions
|
// only check functions
|
||||||
if (func_scope->type == Scope::eFunction) {
|
if (func_scope->type == Scope::eFunction) {
|
||||||
for (const Token *tok = func_scope->classStart; tok && tok != func_scope->classEnd; tok = tok->next()) {
|
for (const Token *tok = func_scope->classStart; tok && tok != func_scope->classEnd; tok = tok->next()) {
|
||||||
// Variable declaration..
|
|
||||||
if (Token::Match(tok, "[;{}] %type% %var% ;") && tok->next()->isStandardType()) {
|
if (Token::Match(tok, "[;{}] %type% !!;")) {
|
||||||
checkScopeForVariable(tok->tokAt(3), tok->tokAt(2)->varId());
|
bool stdtype = false;
|
||||||
|
bool pointer = false;
|
||||||
|
tok = tok->next();
|
||||||
|
while (tok->isName() || tok->str() == "*") {
|
||||||
|
if (tok->isStandardType())
|
||||||
|
stdtype = true;
|
||||||
|
else if (tok->str() == "*")
|
||||||
|
pointer = true;
|
||||||
|
else if (tok->isName() && tok->next()->str() == ";") {
|
||||||
|
if (stdtype || pointer || _tokenizer->isC())
|
||||||
|
checkScopeForVariable(tok->next(), tok->varId(), pointer, NULL);
|
||||||
|
break;
|
||||||
|
} else if (!tok->isName())
|
||||||
|
break;
|
||||||
|
tok = tok->next();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int varid, bool * const possibleInit)
|
bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int varid, bool ispointer, bool * const possibleInit)
|
||||||
{
|
{
|
||||||
if (varid == 0)
|
if (varid == 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -1094,7 +1109,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int
|
||||||
const Token * const endToken = tok->next()->link();
|
const Token * const endToken = tok->next()->link();
|
||||||
for (const Token *tok2 = tok->tokAt(2); tok2 != endToken; tok2 = tok2->next()) {
|
for (const Token *tok2 = tok->tokAt(2); tok2 != endToken; tok2 = tok2->next()) {
|
||||||
if (tok2->varId() == varid) {
|
if (tok2->varId() == varid) {
|
||||||
if (!suppressErrors && isVariableUsage(tok2))
|
if (!suppressErrors && isVariableUsage(tok2, ispointer))
|
||||||
uninitvarError(tok2, tok2->str());
|
uninitvarError(tok2, tok2->str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1106,7 +1121,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int
|
||||||
tok = tok->next()->link()->next();
|
tok = tok->next()->link()->next();
|
||||||
|
|
||||||
bool possibleInitIf(number_of_if > 0);
|
bool possibleInitIf(number_of_if > 0);
|
||||||
const bool initif = checkScopeForVariable(tok->next(), varid, &possibleInitIf);
|
const bool initif = checkScopeForVariable(tok->next(), varid, ispointer, &possibleInitIf);
|
||||||
|
|
||||||
// goto the }
|
// goto the }
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
@ -1126,7 +1141,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int
|
||||||
tok = tok->tokAt(2);
|
tok = tok->tokAt(2);
|
||||||
|
|
||||||
bool possibleInitElse(number_of_if > 0);
|
bool possibleInitElse(number_of_if > 0);
|
||||||
const bool initelse = checkScopeForVariable(tok->next(), varid, &possibleInitElse);
|
const bool initelse = checkScopeForVariable(tok->next(), varid, ispointer, &possibleInitElse);
|
||||||
|
|
||||||
// goto the }
|
// goto the }
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
@ -1175,7 +1190,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int
|
||||||
// variable is seen..
|
// variable is seen..
|
||||||
if (tok->varId() == varid) {
|
if (tok->varId() == varid) {
|
||||||
// Use variable
|
// Use variable
|
||||||
if (!suppressErrors && isVariableUsage(tok))
|
if (!suppressErrors && isVariableUsage(tok, ispointer))
|
||||||
uninitvarError(tok, tok->str());
|
uninitvarError(tok, tok->str());
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -1187,7 +1202,7 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const unsigned int
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckUninitVar::isVariableUsage(const Token *vartok) const
|
bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer) const
|
||||||
{
|
{
|
||||||
if (vartok->previous()->str() == "return")
|
if (vartok->previous()->str() == "return")
|
||||||
return true;
|
return true;
|
||||||
|
@ -1203,6 +1218,10 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool unknown = false;
|
||||||
|
if (pointer && CheckNullPointer::isPointerDeRef(vartok, unknown))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (Token::Match(vartok->next(), "++|--|%op%"))
|
if (Token::Match(vartok->next(), "++|--|%op%"))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -60,8 +60,8 @@ public:
|
||||||
|
|
||||||
/** Check for uninitialized variables */
|
/** Check for uninitialized variables */
|
||||||
void check();
|
void check();
|
||||||
bool checkScopeForVariable(const Token *tok, const unsigned int varid, bool * const possibleInit=0);
|
bool checkScopeForVariable(const Token *tok, const unsigned int varid, bool ispointer, bool * const possibleInit);
|
||||||
bool isVariableUsage(const Token *vartok) const;
|
bool isVariableUsage(const Token *vartok, bool ispointer) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uninitialized variables: analyse functions to see how they work with uninitialized variables
|
* @brief Uninitialized variables: analyse functions to see how they work with uninitialized variables
|
||||||
|
|
|
@ -1733,6 +1733,12 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("void f() {\n"
|
||||||
|
" struct ABC *abc;\n"
|
||||||
|
" abc->a = 0;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: abc\n", errout.str());
|
||||||
|
|
||||||
// using uninit var in condition
|
// using uninit var in condition
|
||||||
checkUninitVar2("void f() {\n"
|
checkUninitVar2("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
|
|
Loading…
Reference in New Issue