From daea0547fa5702a5380a7ac1b186e7dba0dde09c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 10 May 2009 08:01:38 +0200 Subject: [PATCH] memory leaks: Handling exit (#297) --- src/checkmemoryleak.cpp | 21 +++++++++++++++++++++ test/testmemleak.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index abcde6f5c..e71c6541f 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -662,6 +662,10 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list if (Token::Match(tok, "try|throw|catch")) addtoken(tok->strAt(0)); + // exit.. + if (Token::Match(tok->previous(), "[{};] exit ( %any% ) ;")) + addtoken("exit"); + // Assignment.. if (Token::Match(tok, std::string("[)=] " + varnameStr + " [+;)]").c_str()) || Token::Match(tok, std::string(varnameStr + " +=|-=").c_str()) || @@ -771,6 +775,23 @@ void CheckMemoryLeakClass::simplifycode(Token *tok, bool &all) tok2->str("return"); } + + // simplify "exit".. remove everything in its execution path + for (Token *tok2 = tok; tok2; tok2 = tok2->next()) + { + if (tok2->str() != "exit") + continue; + + // Found an "exit".. try to remove everything before it + const Token *tokEnd = tok2->next(); + while (tok2->previous() && !Token::Match(tok2->previous(), "[{}]")) + tok2 = tok2->previous(); + if (tok2->previous()) + tok2 = tok2->previous(); + + Token::eraseTokens(tok2, tokEnd); + } + // reduce the code.. bool done = false; while (! done) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index cd6eeaa00..dd8e8d6fa 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -208,6 +208,11 @@ private: TEST_CASE(free_member_in_sub_func); TEST_CASE(if_with_and); TEST_CASE(assign_pclose); + + // Using the function "exit" + TEST_CASE(exit1); + TEST_CASE(exit2); + } @@ -2121,6 +2126,32 @@ private: "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); } + + void exit1() + { + // Ticket #297 + check("void f()\n" + "{\n" + " char *out = new char[100];\n" + " if (c())\n" + " {\n" + " delete [] out;\n" + " exit(0);\n" + " }\n" + " delete [] out;\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); + } + + void exit2() + { + check("void f()\n" + "{\n" + " char *out = new char[100];\n" + " exit(0);\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); + } }; REGISTER_TEST(TestMemleak)