diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 3ca4ce2d9..acc666f05 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2380,10 +2380,15 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam // Inspect member functions std::list::const_iterator func; for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) { - if (!func->hasBody) - continue; const bool constructor = func->type == Function::eConstructor; const bool destructor = func->type == Function::eDestructor; + if (!func->hasBody) { + if (destructor) { // implementation for destructor is not seen => assume it deallocates all variables properly + deallocInDestructor = true; + Dealloc = CheckMemoryLeak::Many; + } + continue; + } bool body = false; const Token *end = func->functionScope->classEnd; for (const Token *tok = func->arg->link(); tok != end; tok = tok->next()) { diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 077d9762b..b24b83757 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -3935,6 +3935,7 @@ private: TEST_CASE(class22); // ticket #3012 TEST_CASE(class23); // ticket #3303 TEST_CASE(class24); // ticket #3806 - false positive in copy constructor + TEST_CASE(class25); // ticket #4367 - false positive implementation for destructor is not seen TEST_CASE(staticvar); @@ -4848,6 +4849,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void class25() { // ticket #4367 - false positive when implementation for destructor is not seen + check("class Fred {\n" + "private:\n" + " int * a;\n" + "public:\n" + " Fred() { a = new int; }\n" + " ~Fred();\n" + "};\n"); + ASSERT_EQUALS("", errout.str()); + } + void staticvar() { check("class A\n" "{\n"