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"