Fixed #7822 (False positive for uninitialized variable if array type is used)
This commit is contained in:
parent
28af5c0379
commit
d79688c40b
|
@ -46,15 +46,21 @@ void CheckUninitVar::check()
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
std::list<Scope>::const_iterator scope;
|
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
|
// check every executable scope
|
||||||
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
||||||
if (scope->isExecutable()) {
|
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) {
|
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) ||
|
if ((_tokenizer->isCPP() && i->type() && !i->isPointer() && i->type()->needInitialization != Type::True) ||
|
||||||
|
@ -87,7 +93,7 @@ void CheckUninitVar::checkScope(const Scope* scope)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stdtype = _tokenizer->isC();
|
bool stdtype = _tokenizer->isC() && arrayTypeDefs.find(i->typeStartToken()->str()) == arrayTypeDefs.end();
|
||||||
const Token* tok = i->typeStartToken();
|
const Token* tok = i->typeStartToken();
|
||||||
for (; tok != i->nameToken() && tok->str() != "<"; tok = tok->next()) {
|
for (; tok != i->nameToken() && tok->str() != "<"; tok = tok->next()) {
|
||||||
if (tok->isStandardType() || tok->isEnumType())
|
if (tok->isStandardType() || tok->isEnumType())
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
|
|
||||||
/** Check for uninitialized variables */
|
/** Check for uninitialized variables */
|
||||||
void check();
|
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);
|
void checkStruct(const Token *tok, const Variable &structvar);
|
||||||
enum Alloc { NO_ALLOC, NO_CTOR_CALL, CTOR_CALL, ARRAY };
|
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);
|
bool checkScopeForVariable(const Token *tok, const Variable& var, bool* const possibleInit, bool* const noreturn, Alloc* const alloc, const std::string &membervar);
|
||||||
|
|
|
@ -699,6 +699,14 @@ private:
|
||||||
" _tm.dostuff();\n"
|
" _tm.dostuff();\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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
|
void uninitvar3() { // #3844
|
||||||
|
|
Loading…
Reference in New Issue