From 2a77dd3df150e3db7608e07621a03256974b0a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 1 Jan 2011 20:14:01 +0100 Subject: [PATCH] Fixed #2246 (Improve check: Memory leak, function is not noreturn if return value is taken) --- lib/checkmemoryleak.cpp | 7 ++++--- test/testmemleak.cpp | 21 ++++++++++++++++++++- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 3115b8d7b..8c290ea87 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -678,7 +678,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::liststr()) != noreturn.end()) + if (noreturn.find(tok->str()) != noreturn.end() && tok->strAt(-1) != "=") return "exit"; if (varid > 0 && (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No)) @@ -733,12 +733,13 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::listprevious()->str() != "=") ? "callfunc" : NULL; unsigned int par = 1; unsigned int parlevel = 0; const bool dot(tok->previous()->str() == "."); + const bool eq(tok->previous()->str() == "="); for (; tok; tok = tok->next()) { @@ -749,7 +750,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::listinconclusive) ? 0 : "callfunc"; + return (eq || _settings->inconclusive) ? 0 : "callfunc"; } } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index e8ae658f6..46af1ed11 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -292,6 +292,8 @@ private: TEST_CASE(exit2); TEST_CASE(exit4); TEST_CASE(exit5); + TEST_CASE(exit6); + TEST_CASE(exit7); TEST_CASE(noreturn); TEST_CASE(stdstring); @@ -475,9 +477,10 @@ private: ASSERT_EQUALS(";;;", getcode("char *s; s = strcpy(s, p);", "s")); // callfunc.. - ASSERT_EQUALS(";;assigncallfunc;", getcode("char *s; s = a();", "s")); + ASSERT_EQUALS(";;assign;", getcode("char *s; s = a();", "s")); ASSERT_EQUALS(";;callfunc;", getcode("char *s; a();", "s")); ASSERT_EQUALS(";;callfunc;", getcode("char *s; abc.a();", "s")); + ASSERT_EQUALS(";;;", getcode("char *s; x = a();", "s")); // the function call is irrelevant // exit.. ASSERT_EQUALS(";;exit;", getcode("char *s; exit(0);", "s")); @@ -2585,6 +2588,22 @@ private: ASSERT_EQUALS("", errout.str()); } + void exit7() + { + check("int a(int x) {\n" + " if (x == 0) {\n" + " exit(0);\n" + " }\n" + " return x + 2;\n" + "}\n" + "\n" + "void b() {\n" + " char *p = malloc(100);\n" + " int i = a(123);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:11]: (error) Memory leak: p\n", errout.str()); + } + void noreturn() { check("void fatal_error()\n"