From d79688c40b52307f5ce3085fa9555094bfd8ff64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 21 Dec 2016 23:11:11 +0100 Subject: [PATCH] Fixed #7822 (False positive for uninitialized variable if array type is used) --- lib/checkuninitvar.cpp | 12 +++++++++--- lib/checkuninitvar.h | 2 +- test/testuninitvar.cpp | 8 ++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 564ccb12f..5dbcf228a 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -46,15 +46,21 @@ void CheckUninitVar::check() const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); std::list::const_iterator scope; + std::set 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 &arrayTypeDefs) { for (std::list::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()) diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index 64064b1d9..743161095 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -54,7 +54,7 @@ public: /** Check for uninitialized variables */ void check(); - void checkScope(const Scope* scope); + void checkScope(const Scope* scope, const std::set &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); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index 54fbb674c..8eb75ae27 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -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