From 81318b3f4a85634d899567e5d6173eab22c710cc Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 14 Mar 2012 22:24:43 +0100 Subject: [PATCH 1/4] Detect and display an error on leaks due to return of a function that allocates something is ignored. This fixes #3439 --- lib/checkmemoryleak.cpp | 10 ++++++++++ lib/checkmemoryleak.h | 2 ++ 2 files changed, 12 insertions(+) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 064336a47..b8043a869 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2879,6 +2879,11 @@ void CheckMemoryLeakNoVar::check() } } } + + // Handle the case were the user is calling a function returning something which is leaking + // and never assigns the returned value to a variable, which will lead to a leak. + else if (Token::Match(tok2, "[;{}] %var% (") && getAllocationType(tok2->next(), 0) != No) + missingAssignementLeak(tok2, tok2->next()->str()); } } } @@ -2888,4 +2893,9 @@ void CheckMemoryLeakNoVar::functionCallLeak(const Token *loc, const std::string reportError(loc, Severity::error, "leakNoVarFunctionCall", "Allocation with " + alloc + ", " + functionCall + " doesn't release it."); } +void CheckMemoryLeakNoVar::missingAssignementLeak(const Token *loc, const std::string &alloc) +{ + reportError(loc, Severity::error, "leakNoVar", "Allocation with " + alloc + " never assigned."); +} + diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 4ad6977f7..8cceca537 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -456,6 +456,8 @@ private: void functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall); + void missingAssignementLeak(const Token *loc, const std::string &alloc); + void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) const { } From f3b1c46c7df95fcc052b1f17e694a29ffdcb044a Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 14 Mar 2012 23:44:04 +0100 Subject: [PATCH 2/4] Define error messages for --errorlist for CheckMemoryLeakNoVar class --- lib/checkmemoryleak.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 8cceca537..7fbec37e3 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -452,15 +452,19 @@ public: void check(); + void getErrorMessages(ErrorLogger *e, const Settings *settings) const { + CheckMemoryLeakNoVar c(0, settings, e); + + c.functionCallLeak(0, "funcName", "funcName"); + c.missingAssignementLeak(0, "funcName"); + } + private: void functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall); void missingAssignementLeak(const Token *loc, const std::string &alloc); - void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) const - { } - std::string myName() const { return "Memory leaks (address not taken)"; } From 5dc4fcaa0aa5ee0284735cd92b436e00163a6f1b Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Wed, 14 Mar 2012 23:45:20 +0100 Subject: [PATCH 3/4] Add two tests for the new memory leak detection --- test/testmemleak.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 46862745a..d2dde8d32 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -5198,6 +5198,8 @@ private: void run() { // pass allocated memory to function.. TEST_CASE(functionParameter); + // never use leakable resource + TEST_CASE(missingAssignement); } void functionParameter() { @@ -5235,5 +5237,23 @@ private: "}\n"); TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Allocation with strdup, mkstemp doesn't release it.\n", "", errout.str()); } + + void missingAssignement() { + check("void x()\n" + "{\n" + " malloc(10);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2]: (error) Allocation with malloc never assigned.\n", errout.str()); + + check("void *f()\n" + "{\n" + " return malloc(10);\n" + "}\n" + "void x()\n" + "{\n" + " f();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6]: (error) Allocation with f never assigned.\n", errout.str()); + } }; static TestMemleakNoVar testMemleakNoVar; From e9a696f70ea2abd3917305f10095fc618d117f14 Mon Sep 17 00:00:00 2001 From: Pierre Schweitzer Date: Thu, 15 Mar 2012 18:52:51 +0100 Subject: [PATCH 4/4] Set back getErrorMessages() as private --- lib/checkmemoryleak.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 7fbec37e3..7d595dbe3 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -452,6 +452,12 @@ public: void check(); +private: + + void functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall); + + void missingAssignementLeak(const Token *loc, const std::string &alloc); + void getErrorMessages(ErrorLogger *e, const Settings *settings) const { CheckMemoryLeakNoVar c(0, settings, e); @@ -459,12 +465,6 @@ public: c.missingAssignementLeak(0, "funcName"); } -private: - - void functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall); - - void missingAssignementLeak(const Token *loc, const std::string &alloc); - std::string myName() const { return "Memory leaks (address not taken)"; }