Fixed #7822 (False positive for uninitialized variable if array type is used)

This commit is contained in:
Daniel Marjamäki 2016-12-21 23:11:11 +01:00
parent 28af5c0379
commit d79688c40b
3 changed files with 18 additions and 4 deletions

View File

@ -46,15 +46,21 @@ void CheckUninitVar::check()
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope>::const_iterator scope;
std::set<std::string> arrayTypeDefs;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
if (Token::Match(tok, "%name% [") && tok->variable() && Token::Match(tok->variable()->typeStartToken(), "%type% %var% ;"))
arrayTypeDefs.insert(tok->variable()->typeStartToken()->str());
}
// check every executable scope
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
if (scope->isExecutable()) {
checkScope(&*scope);
checkScope(&*scope, arrayTypeDefs);
}
}
}
void CheckUninitVar::checkScope(const Scope* scope)
void CheckUninitVar::checkScope(const Scope* scope, const std::set<std::string> &arrayTypeDefs)
{
for (std::list<Variable>::const_iterator i = scope->varlist.begin(); i != scope->varlist.end(); ++i) {
if ((_tokenizer->isCPP() && i->type() && !i->isPointer() && i->type()->needInitialization != Type::True) ||
@ -87,7 +93,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
continue;
}
bool stdtype = _tokenizer->isC();
bool stdtype = _tokenizer->isC() && arrayTypeDefs.find(i->typeStartToken()->str()) == arrayTypeDefs.end();
const Token* tok = i->typeStartToken();
for (; tok != i->nameToken() && tok->str() != "<"; tok = tok->next()) {
if (tok->isStandardType() || tok->isEnumType())

View File

@ -54,7 +54,7 @@ public:
/** Check for uninitialized variables */
void check();
void checkScope(const Scope* scope);
void checkScope(const Scope* scope, const std::set<std::string> &arrayTypeDefs);
void checkStruct(const Token *tok, const Variable &structvar);
enum Alloc { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY };
bool checkScopeForVariable(const Token *tok, const Variable& var, bool* const possibleInit, bool* const noreturn, Alloc* const alloc, const std::string &membervar);

View File

@ -699,6 +699,14 @@ private:
" _tm.dostuff();\n"
"}");
ASSERT_EQUALS("", errout.str());
// Ticket #7822 - Array type
checkUninitVar("A *f() {\n"
" A a,b;\n"
" b[0] = 0;"
" return a;\n"
"}", "test.c", false);
ASSERT_EQUALS("", errout.str());
}
void uninitvar3() { // #3844