Fixed #3506 (false negative: not initialized variables ( struct timeval))

This commit is contained in:
Daniel Marjamki 2013-01-19 12:48:56 +01:00
parent 7c4f0e594b
commit f1c195e652
3 changed files with 21 additions and 15 deletions

View File

@ -1081,7 +1081,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
while (tok && tok->str() != ";") while (tok && tok->str() != ";")
tok = tok->next(); tok = tok->next();
if (stdtype || i->isPointer()) if (stdtype || i->isPointer())
checkScopeForVariable(scope, tok, *i, NULL, NULL, NULL); checkScopeForVariable(scope, tok, *i, NULL, NULL, "");
if (Token::Match(i->typeStartToken(), "struct %type% %var% ;")) { if (Token::Match(i->typeStartToken(), "struct %type% %var% ;")) {
const std::string structname(i->typeStartToken()->next()->str()); const std::string structname(i->typeStartToken()->next()->str());
const SymbolDatabase * symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase * symbolDatabase = _tokenizer->getSymbolDatabase();
@ -1089,7 +1089,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
const Scope *scope2 = symbolDatabase->classAndStructScopes[j]; const Scope *scope2 = symbolDatabase->classAndStructScopes[j];
if (scope2->className == structname && scope2->numConstructors == 0U) { if (scope2->className == structname && scope2->numConstructors == 0U) {
for (std::list<Variable>::const_iterator it = scope2->varlist.begin(); it != scope2->varlist.end(); ++it) for (std::list<Variable>::const_iterator it = scope2->varlist.begin(); it != scope2->varlist.end(); ++it)
checkScopeForVariable(scope, tok, *i, NULL, NULL, &(*it)); checkScopeForVariable(scope, tok, *i, NULL, NULL, it->name());
} }
} }
} }
@ -1101,7 +1101,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
} }
} }
bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const Variable * const membervar) bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const std::string &membervar)
{ {
const bool suppressErrors(possibleInit && *possibleInit); const bool suppressErrors(possibleInit && *possibleInit);
@ -1156,7 +1156,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
} }
// initialization / usage in condition.. // initialization / usage in condition..
if (!alwaysTrue && checkIfForWhileHead(scope, tok->next(), var, suppressErrors || (membervar != NULL), bool(number_of_if == 0))) if (!alwaysTrue && checkIfForWhileHead(scope, tok->next(), var, suppressErrors, bool(number_of_if == 0), membervar))
return true; return true;
// checking if a not-zero variable is zero => bail out // checking if a not-zero variable is zero => bail out
@ -1281,7 +1281,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
// for/while.. // for/while..
if (Token::Match(tok, "for|while (")) { if (Token::Match(tok, "for|while (")) {
// is variable initialized in for-head (don't report errors yet)? // is variable initialized in for-head (don't report errors yet)?
if (checkIfForWhileHead(scope, tok->next(), var, true, false)) if (checkIfForWhileHead(scope, tok->next(), var, true, false, membervar))
return true; return true;
// goto the { // goto the {
@ -1297,7 +1297,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
// is variable used in for-head? // is variable used in for-head?
if (!suppressErrors) { if (!suppressErrors) {
checkIfForWhileHead(scope, tok->next(), var, false, bool(number_of_if == 0)); checkIfForWhileHead(scope, tok->next(), var, false, bool(number_of_if == 0), membervar);
} }
// goto "}" // goto "}"
@ -1321,7 +1321,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
while (tok && tok->str() != ";") { while (tok && tok->str() != ";") {
// variable is seen.. // variable is seen..
if (tok->varId() == var.varId() && (membervar == NULL)) { if (tok->varId() == var.varId() && (membervar.empty())) {
// Use variable // Use variable
if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer())) if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer()))
uninitvarError(tok, tok->str()); uninitvarError(tok, tok->str());
@ -1342,12 +1342,12 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
// variable is seen.. // variable is seen..
if (tok->varId() == var.varId()) { if (tok->varId() == var.varId()) {
if (membervar) { if (!membervar.empty()) {
if (Token::Match(tok, "%var% . %var%") && tok->strAt(2) == membervar->name()) { if (Token::Match(tok, "%var% . %var%") && tok->strAt(2) == membervar) {
if (Token::Match(tok->tokAt(3), "[=.[]")) if (Token::Match(tok->tokAt(3), "[=.[]"))
return true; return true;
else if (Token::Match(tok->previous(), "%op%") || Token::Match(tok->previous(), "[|=")) else if (Token::Match(tok->previous(), "%op%") || Token::Match(tok->previous(), "[|="))
uninitStructMemberError(tok, tok->str() + "." + membervar->name()); uninitStructMemberError(tok, tok->str() + "." + membervar);
else else
return true; return true;
} else if (tok->strAt(1) == "=") } else if (tok->strAt(1) == "=")
@ -1355,7 +1355,7 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
else if (tok->strAt(-1) == "&") else if (tok->strAt(-1) == "&")
return true; return true;
else if (Token::Match(tok->previous(), "[(,] %var% [,)]") && isVariableUsage(scope, tok, var.isPointer())) else if (Token::Match(tok->previous(), "[(,] %var% [,)]") && isVariableUsage(scope, tok, var.isPointer()))
uninitStructMemberError(tok, tok->str() + "." + membervar->name()); uninitStructMemberError(tok, tok->str() + "." + membervar);
} else { } else {
// Use variable // Use variable
if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer())) if (!suppressErrors && isVariableUsage(scope, tok, var.isPointer()))
@ -1371,11 +1371,17 @@ bool CheckUninitVar::checkScopeForVariable(const Scope* scope, const Token *tok,
return false; return false;
} }
bool CheckUninitVar::checkIfForWhileHead(const Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit) bool CheckUninitVar::checkIfForWhileHead(const Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, const std::string &membervar)
{ {
const Token * const endpar = startparentheses->link(); const Token * const endpar = startparentheses->link();
for (const Token *tok = startparentheses->next(); tok && tok != endpar; tok = tok->next()) { for (const Token *tok = startparentheses->next(); tok && tok != endpar; tok = tok->next()) {
if (tok->varId() == var.varId()) { if (tok->varId() == var.varId()) {
if (Token::Match(tok, "%var% . %var%")) {
if (tok->strAt(2) == membervar)
uninitStructMemberError(tok, tok->str() + "." + membervar);
continue;
}
if (isVariableUsage(scope, tok, var.isPointer())) { if (isVariableUsage(scope, tok, var.isPointer())) {
if (!suppressErrors) if (!suppressErrors)
uninitvarError(tok, tok->str()); uninitvarError(tok, tok->str());

View File

@ -64,8 +64,8 @@ public:
/** Check for uninitialized variables */ /** Check for uninitialized variables */
void check(); void check();
void checkScope(const Scope* scope); void checkScope(const Scope* scope);
bool checkScopeForVariable(const Scope* scope, const Token *tok, const Variable& var, bool * const possibleInit, bool * const noreturn, const Variable * const 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 Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit); bool checkIfForWhileHead(const Scope *scope, const Token *startparentheses, const Variable& var, bool suppressErrors, bool isuninit, const std::string &membervar);
bool isVariableUsage(const Scope* scope, const Token *vartok, bool ispointer) const; bool isVariableUsage(const Scope* scope, const Token *vartok, bool ispointer) const;

View File

@ -2661,7 +2661,7 @@ private:
" fred.a = do_something();\n" " fred.a = do_something();\n"
" if (fred.b == 0) { }\n" " if (fred.b == 0) { }\n"
"}\n", "test.c", true); "}\n", "test.c", true);
TODO_ASSERT_EQUALS("error", "", errout.str()); ASSERT_EQUALS("[test.c:9]: (error) Uninitialized struct member: fred.b\n", errout.str());
} }
}; };