From 74086740172d1d9dfdaf5501a5f22aa1f48d32a6 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Thu, 3 Sep 2009 23:28:00 +0300 Subject: [PATCH] Fix #601 (Poor var initialization assumption when can't find function definition) http://sourceforge.net/apps/trac/cppcheck/ticket/601 Fix #641 ((style) Member variable not initialized in the constructor: False Positive) http://sourceforge.net/apps/trac/cppcheck/ticket/641 This fix will also cause us not to detect several potential issues, but as there are so many false positives, any unknown function call should stop the error for now. New ticket is created to handle regression caused by this: http://sourceforge.net/apps/trac/cppcheck/ticket/643 --- src/checkclass.cpp | 15 ++++++++++++++- test/testclass.cpp | 30 ++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/checkclass.cpp b/src/checkclass.cpp index f97c9431f..841224296 100644 --- a/src/checkclass.cpp +++ b/src/checkclass.cpp @@ -263,7 +263,20 @@ void CheckClass::initializeVarList(const Token *tok1, const Token *ftok, Var *va callstack.push_back(ftok->str()); int i = 0; const Token *ftok2 = Tokenizer::findClassFunction(tok1, classname, ftok->strAt(0), i); - initializeVarList(tok1, ftok2, varlist, classname, callstack); + if (ftok2) + { + initializeVarList(tok1, ftok2, varlist, classname, callstack); + } + else // there is a called member function, but it is not defined where we can find it, so we assume it initializes everything + { + for (Var *var = varlist; var; var = var->next) + var->init = true; + break; + + // we don't report this, as somewhere along the line we hope that the class and member function + // are checked together. It is possible that this will not be the case (where there are enough + // nested functions defined in different files), but that isn't really likely. + } } } diff --git a/test/testclass.cpp b/test/testclass.cpp index 65becb5ed..e61ddfe12 100644 --- a/test/testclass.cpp +++ b/test/testclass.cpp @@ -49,6 +49,7 @@ private: TEST_CASE(uninitVarStream); TEST_CASE(uninitVarTypedef); TEST_CASE(uninitVarArray); + TEST_CASE(uninitMissingFuncDef);// can't expand function in constructor TEST_CASE(privateCtor1); // If constructor is private.. TEST_CASE(privateCtor2); // If constructor is private.. TEST_CASE(function); // Function is not variable @@ -64,7 +65,6 @@ private: TEST_CASE(operatorEq1); TEST_CASE(memsetOnStruct); TEST_CASE(memsetOnClass); - } // Check the operator Equal @@ -429,7 +429,31 @@ private: " char name[255];\n" "};\n"); - TODO_ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("", errout.str()); + } + + void uninitMissingFuncDef() + { + // Unknown member function + checkUninitVar("class Fred\n" + "{\n" + "public:\n" + " Fred() { Init(); }\n" + "private:\n" + " void Init();" + " int i;\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + + // Unknown non-member function + checkUninitVar("class Fred\n" + "{\n" + "public:\n" + " Fred() { Init(); }\n" + "private:\n" + " int i;\n" + "};\n"); + TODO_ASSERT_EQUALS("[test.cpp:4]: (style) Member variable not initialized in the constructor 'Fred::i'\n", errout.str()); } void uninitVarEnum() @@ -700,8 +724,6 @@ private: "}\n"); ASSERT_EQUALS("[test.cpp:10]: (error) Using 'memset' on struct that contains a 'std::string'\n", errout.str()); } - - }; REGISTER_TEST(TestClass)