From 04b811b74faf4a421940dea4ec23fd48989e52e0 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Sat, 4 Dec 2010 17:47:00 +0100 Subject: [PATCH] Fixed #2273 (False Positive: Member variable not initialized in the constructor) --- lib/checkclass.cpp | 4 +++- lib/symboldatabase.cpp | 14 ++++++++++++++ test/testclass.cpp | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index a16c27225..3d8fdf409 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -109,7 +109,9 @@ void CheckClass::constructors() for (func = info->functionList.begin(); func != info->functionList.end(); ++func) { - if (!func->hasBody || !(func->type == SymbolDatabase::Func::Constructor || func->type == SymbolDatabase::Func::CopyConstructor || func->type == SymbolDatabase::Func::OperatorEqual)) + if (!func->hasBody || !(func->type == SymbolDatabase::Func::Constructor || + func->type == SymbolDatabase::Func::CopyConstructor || + func->type == SymbolDatabase::Func::OperatorEqual)) continue; // Mark all variables not used diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index f18f1b6fe..a909b427c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1459,8 +1459,22 @@ void SymbolDatabase::SpaceInfo::initializeVarList(const Func &func, std::listnext(), "%var% . %var% (")) + { + std::list::const_iterator var; + for (var = varlist.begin(); var != varlist.end(); ++var) + { + if (var->token->varId() == ftok->next()->varId()) + { + /** @todo false negative: we assume function changes variable state */ + assignVar(ftok->next()->str()); + continue; + } + } + ftok = ftok->tokAt(2); + } if (!Token::Match(ftok->next(), "%var%") && !Token::Match(ftok->next(), "this . %var%") && diff --git a/test/testclass.cpp b/test/testclass.cpp index b868feb27..edcbd97c4 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -59,6 +59,7 @@ private: TEST_CASE(uninitVar13); // ticket #1195 TEST_CASE(uninitVar14); // ticket #2149 TEST_CASE(uninitVar15); + TEST_CASE(uninitVar16); TEST_CASE(uninitVarEnum); TEST_CASE(uninitVarStream); TEST_CASE(uninitVarTypedef); @@ -1952,6 +1953,40 @@ private: ASSERT_EQUALS("", errout.str()); } + void uninitVar16() + { + checkUninitVar("struct Foo\n" + "{\n" + " int a;\n" + " void set(int x) { a = x; }\n" + "};\n" + "class Bar\n" + "{\n" + " Foo foo;\n" + "public:\n" + " Bar()\n" + " {\n" + " foo.set(0);\n" + " }\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + checkUninitVar("struct Foo\n" + "{\n" + " int a;\n" + " void set(int x) { a = x; }\n" + "};\n" + "class Bar\n" + "{\n" + " Foo foo;\n" + "public:\n" + " Bar()\n" + " {\n" + " }\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:10]: (warning) Member variable not initialized in the constructor 'Bar::foo'\n", errout.str()); + } + void uninitVarArray1() { checkUninitVar("class John\n"