Fixed #4082 (Maybe false positive: memleak)

This commit is contained in:
Daniel Marjamäki 2012-09-10 17:27:41 +02:00
parent 3449684137
commit 54f1771938
3 changed files with 41 additions and 29 deletions

View File

@ -2440,12 +2440,19 @@ void CheckMemoryLeakInClass::variable(const Scope *scope, const Token *tokVarnam
} }
if (allocInConstructor && !deallocInDestructor) { if (allocInConstructor && !deallocInDestructor) {
memoryLeak(tokVarname, classname + "::" + varname, Alloc); unsafeClassError(tokVarname, classname, classname + "::" + varname /*, Alloc*/);
} else if (Alloc != CheckMemoryLeak::No && Dealloc == CheckMemoryLeak::No) { } else if (Alloc != CheckMemoryLeak::No && Dealloc == CheckMemoryLeak::No) {
memoryLeak(tokVarname, classname + "::" + varname, Alloc); unsafeClassError(tokVarname, classname, classname + "::" + varname /*, Alloc*/);
} }
} }
void CheckMemoryLeakInClass::unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname)
{
reportError(tok, Severity::style, "unsafeClassCanLeak",
"Class '" + classname + "' is unsafe, '" + varname + "' can leak by wrong usage.\n"
"The class '" + classname + "' is unsafe, wrong usage can cause memory/resource leaks for '" + varname + "'. This can for instance be fixed by adding proper cleanup in the destructor.");
}
void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Token *classtok) void CheckMemoryLeakInClass::checkPublicFunctions(const Scope *scope, const Token *classtok)
{ {

View File

@ -379,8 +379,13 @@ private:
void checkPublicFunctions(const Scope *scope, const Token *classtok); void checkPublicFunctions(const Scope *scope, const Token *classtok);
void publicAllocationError(const Token *tok, const std::string &varname); void publicAllocationError(const Token *tok, const std::string &varname);
void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) const void unsafeClassError(const Token *tok, const std::string &classname, const std::string &varname);
{ }
void getErrorMessages(ErrorLogger *e, const Settings *settings) const {
CheckMemoryLeakInClass c(0, settings, e);
c.publicAllocationError(0, "varname");
c.unsafeClassError(0, "class", "class::varname");
}
static std::string myName() { static std::string myName() {
return "Memory leaks (class variables)"; return "Memory leaks (class variables)";

View File

@ -3916,7 +3916,7 @@ private:
"{\n" "{\n"
" delete [] str2;\n" " delete [] str2;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: Fred::str1\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str());
check("class Fred\n" check("class Fred\n"
"{\n" "{\n"
@ -3934,7 +3934,7 @@ private:
" delete [] str2;\n" " delete [] str2;\n"
" }\n" " }\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: Fred::str1\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str());
} }
void class2() { void class2() {
@ -4211,7 +4211,7 @@ private:
"};\n" "};\n"
"A::A()\n" "A::A()\n"
"{ p = new int; }\n"); "{ p = new int; }\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: A::p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
"{\n" "{\n"
@ -4219,7 +4219,7 @@ private:
" int * p;\n" " int * p;\n"
" A() { p = new int; }\n" " A() { p = new int; }\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: A::p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
} }
void class11() { void class11() {
@ -4230,7 +4230,7 @@ private:
" A() : p(new int[10])\n" " A() : p(new int[10])\n"
" { }" " { }"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: A::p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
"{\n" "{\n"
@ -4240,7 +4240,7 @@ private:
"};\n" "};\n"
"A::A() : p(new int[10])\n" "A::A() : p(new int[10])\n"
"{ }"); "{ }");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: A::p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
} }
void class12() { void class12() {
@ -4262,7 +4262,7 @@ private:
"\n" "\n"
"void A::cleanup()\n" "void A::cleanup()\n"
"{ delete [] p; }\n"); "{ delete [] p; }\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: A::p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
"{\n" "{\n"
@ -4276,7 +4276,7 @@ private:
" void cleanup()\n" " void cleanup()\n"
" { delete [] p; }\n" " { delete [] p; }\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: A::p\n", errout.str()); ASSERT_EQUALS("[test.cpp:4]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
} }
void class13() { void class13() {
@ -4326,7 +4326,7 @@ private:
"void A::init()\n" "void A::init()\n"
"{ p = new int[10]; }\n"); "{ p = new int[10]; }\n");
ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n"
"[test.cpp:3]: (error) Memory leak: A::p\n", errout.str()); "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
"{\n" "{\n"
@ -4336,7 +4336,7 @@ private:
" { p = new int[10]; }\n" " { p = new int[10]; }\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n"
"[test.cpp:3]: (error) Memory leak: A::p\n", errout.str()); "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
@ -4349,7 +4349,7 @@ private:
"void A::init()\n" "void A::init()\n"
"{ p = new int; }\n"); "{ p = new int; }\n");
ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n"
"[test.cpp:3]: (error) Memory leak: A::p\n", errout.str()); "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
"{\n" "{\n"
@ -4359,7 +4359,7 @@ private:
" { p = new int; }\n" " { p = new int; }\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n"
"[test.cpp:3]: (error) Memory leak: A::p\n", errout.str()); "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
@ -4372,7 +4372,7 @@ private:
"void A::init()\n" "void A::init()\n"
"{ p = malloc(sizeof(int)*10); }\n"); "{ p = malloc(sizeof(int)*10); }\n");
ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" ASSERT_EQUALS("[test.cpp:9]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n"
"[test.cpp:3]: (error) Memory leak: A::p\n", errout.str()); "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
check("class A\n" check("class A\n"
"{\n" "{\n"
@ -4382,7 +4382,7 @@ private:
" { p = malloc(sizeof(int)*10); }\n" " { p = malloc(sizeof(int)*10); }\n"
"};\n"); "};\n");
ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n" ASSERT_EQUALS("[test.cpp:6]: (warning) Possible leak in public function. The pointer 'p' is not deallocated before it is allocated.\n"
"[test.cpp:3]: (error) Memory leak: A::p\n", errout.str()); "[test.cpp:3]: (style) Class 'A' is unsafe, 'A::p' can leak by wrong usage.\n", errout.str());
} }
void class15() { void class15() {
@ -4569,8 +4569,8 @@ private:
" rp1 = new TRadioButton;\n" " rp1 = new TRadioButton;\n"
" rp2 = new TRadioButton;\n" " rp2 = new TRadioButton;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: Foo::rp1\n" ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Foo' is unsafe, 'Foo::rp1' can leak by wrong usage.\n"
"[test.cpp:6]: (error) Memory leak: Foo::rp2\n", errout.str()); "[test.cpp:6]: (style) Class 'Foo' is unsafe, 'Foo::rp2' can leak by wrong usage.\n", errout.str());
check("class TRadioButton { };\n" check("class TRadioButton { };\n"
"class Foo\n" "class Foo\n"
@ -4614,7 +4614,7 @@ private:
" }\n" " }\n"
" };\n" " };\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: Fred::str1\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str());
check("namespace ns1 {\n" check("namespace ns1 {\n"
" class Fred\n" " class Fred\n"
@ -4638,7 +4638,7 @@ private:
" delete [] str2;\n" " delete [] str2;\n"
" }\n" " }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: Fred::str1\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str());
check("namespace ns1 {\n" check("namespace ns1 {\n"
" class Fred\n" " class Fred\n"
@ -4661,7 +4661,7 @@ private:
"{\n" "{\n"
" delete [] str2;\n" " delete [] str2;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:5]: (error) Memory leak: Fred::str1\n", errout.str()); ASSERT_EQUALS("[test.cpp:5]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str());
check("namespace ns1 {\n" check("namespace ns1 {\n"
" namespace ns2 {\n" " namespace ns2 {\n"
@ -4686,7 +4686,7 @@ private:
"{\n" "{\n"
" delete [] str2;\n" " delete [] str2;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Memory leak: Fred::str1\n", errout.str()); ASSERT_EQUALS("[test.cpp:6]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str());
check("namespace ns1 {\n" check("namespace ns1 {\n"
" namespace ns2 {\n" " namespace ns2 {\n"
@ -4713,7 +4713,7 @@ private:
"{\n" "{\n"
" delete [] str2;\n" " delete [] str2;\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:7]: (error) Memory leak: Fred::str1\n", errout.str()); ASSERT_EQUALS("[test.cpp:7]: (style) Class 'Fred' is unsafe, 'Fred::str1' can leak by wrong usage.\n", errout.str());
} }
void class21() { // ticket #2517 void class21() { // ticket #2517
@ -4730,8 +4730,8 @@ private:
"public:\n" "public:\n"
" A() : b(new B()), c(new C(b)) { }\n" " A() : b(new B()), c(new C(b)) { }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: A::b\n" ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n"
"[test.cpp:10]: (error) Memory leak: A::c\n", errout.str()); "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str());
check("struct B { };\n" check("struct B { };\n"
"struct C\n" "struct C\n"
@ -4750,8 +4750,8 @@ private:
" c = new C(b);\n" " c = new C(b);\n"
" }\n" " }\n"
"}\n"); "}\n");
ASSERT_EQUALS("[test.cpp:9]: (error) Memory leak: A::b\n" ASSERT_EQUALS("[test.cpp:9]: (style) Class 'A' is unsafe, 'A::b' can leak by wrong usage.\n"
"[test.cpp:10]: (error) Memory leak: A::c\n", errout.str()); "[test.cpp:10]: (style) Class 'A' is unsafe, 'A::c' can leak by wrong usage.\n", errout.str());
} }
void class22() { // ticket #3012 - false positive void class22() { // ticket #3012 - false positive