diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 05d4dcf20..2245dee99 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -103,11 +103,14 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2, const Token *typeTok = tok2->next(); while (Token::Match(typeTok, "%name% :: %name%")) typeTok = typeTok->tokAt(2); + const Scope* classScope = nullptr; if (typeTok->type() && typeTok->type()->isClassType()) { - const Scope *classScope = typeTok->type()->classScope; - if (classScope && classScope->numConstructors > 0) - return No; + classScope = typeTok->type()->classScope; + } else if (typeTok->function() && typeTok->function()->isConstructor()) { + classScope = typeTok->function()->nestedIn; } + if (classScope && classScope->numConstructors > 0) + return No; return New; } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 9831ab629..cfcbdc833 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -69,8 +69,8 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti createSymbolDatabaseSetVariablePointers(); setValueTypeInTokenList(false); createSymbolDatabaseSetTypePointers(); - createSymbolDatabaseSetSmartPointerType(); createSymbolDatabaseSetFunctionPointers(true); + createSymbolDatabaseSetSmartPointerType(); setValueTypeInTokenList(false); createSymbolDatabaseEnums(); createSymbolDatabaseEscapeFunctions(); diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index fabb168c1..8cf7d5f77 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -1360,8 +1360,10 @@ private: "public:\n" " A() : b(new B()), c(new C(b)) { }\n" "}"); - ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" - "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" + "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", + "[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n", + errout.str()); check("struct B { };\n" "struct C\n" @@ -1380,8 +1382,10 @@ private: " c = new C(b);\n" " }\n" "}"); - ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" - "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str()); + TODO_ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n" + "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", + "[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n", + errout.str()); } void class22() { // ticket #3012 - false positive @@ -2521,6 +2525,26 @@ private: " makeThing();\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #10631 + check("struct Thing {\n" + " Thing();\n" + "};\n" + "std::vector g_things;\n" + "Thing* makeThing() {\n" + " Thing* n = new Thing();\n" + " return n;\n" + "}\n" + "Thing::Thing() {\n" + " g_things.push_back(this);\n" + "}\n" + "void f() {\n" + " makeThing();\n" + " for(Thing* t : g_things) {\n" + " delete t;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } }; REGISTER_TEST(TestMemleakNoVar)