diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 61391c3bb..996d023fa 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -3040,173 +3040,6 @@ void CheckMemoryLeakStructMember::check() - -/** @brief Experimental class for detecting memory leaks. The ExecutionPath functionality is used */ -class CheckLocalLeaks : public ExecutionPath -{ -public: - /** Startup constructor */ - CheckLocalLeaks(Check *c) : ExecutionPath(c, 0), allocated(false) - { - } - - /** Debugging : print checks */ - static void printOut(const std::list &checks) - { - std::ostringstream ostr; - ostr << "CheckLocalLeaks::printOut" << std::endl; - for (std::list::const_iterator it = checks.begin(); it != checks.end(); ++it) - { - CheckLocalLeaks *c = dynamic_cast(*it); - if (c) - { - ostr << std::hex << c << ": varId=" << c->varId << " allocated=" << (c->allocated ? "true" : "false") << std::endl; - } - } - std::cout << ostr.str(); - } - -private: - ExecutionPath *copy() - { - return new CheckLocalLeaks(*this); - } - - /** start checking of given variable */ - CheckLocalLeaks(Check *c, unsigned int v, const std::string &s) : ExecutionPath(c, v), allocated(false), varname(s) - { - } - - /** is other execution path equal? */ - bool is_equal(const ExecutionPath *e) const - { - const CheckLocalLeaks *c = static_cast(e); - return (allocated == c->allocated && varname == c->varname); - } - - /** Is variable allocated? */ - bool allocated; - - /** Name of variable */ - const std::string varname; - - /** no implementation => compiler error if used */ - void operator=(const CheckLocalLeaks &); - - /** Allocation is detected */ - static void alloc(std::list &checks, const unsigned int varid) - { - if (varid == 0) - return; - - std::list::iterator it; - for (it = checks.begin(); it != checks.end(); ++it) - { - CheckLocalLeaks *C = dynamic_cast(*it); - if (C && C->varId == varid) - C->allocated = true; - } - } - - /** Deallocation is detected */ - static void dealloc(std::list &checks, const Token *tok) - { - if (tok->varId() == 0) - return; - - std::list::iterator it; - for (it = checks.begin(); it != checks.end(); ++it) - { - CheckLocalLeaks *C = dynamic_cast(*it); - if (C && C->varId == tok->varId()) - C->allocated = false; - } - } - - /** return */ - static void ret(const std::list &checks, const Token *tok) - { - std::list::const_iterator it; - for (it = checks.begin(); it != checks.end(); ++it) - { - CheckLocalLeaks *C = dynamic_cast(*it); - if (C && C->allocated) - { - CheckMemoryLeakInFunction *checkMemleak = reinterpret_cast(C->owner); - if (checkMemleak) - { - checkMemleak->memleakError(tok, C->varname); - break; - } - } - } - } - - /** parse the tokens */ - const Token *parse(const Token &tok, std::list &checks) const - { - //std::cout << "CheckLocalLeaks::parse " << tok.str() << std::endl; - //printOut(checks); - - if (!Token::Match(tok.previous(), "[;{}]")) - return &tok; - - if (Token::Match(&tok, "%type% * %var% ;")) - { - const Token * vartok = tok.tokAt(2); - if (vartok->varId() != 0) - checks.push_back(new CheckLocalLeaks(owner, vartok->varId(), vartok->str())); - return vartok->next(); - } - - if (Token::Match(&tok, "%var% = new")) - { - alloc(checks, tok.varId()); - - // goto end of statement - const Token *tok2 = &tok; - while (tok2 && tok2->str() != ";") - tok2 = tok2->next(); - return tok2; - } - - if (Token::Match(&tok, "delete %var% ;")) - { - dealloc(checks, tok.next()); - return tok.tokAt(2); - } - - if (Token::Match(&tok, "delete [ ] %var% ;")) - { - dealloc(checks, tok.tokAt(3)); - return tok.tokAt(4); - } - - if (tok.str() == "return") - { - ret(checks, &tok); - } - - return &tok; - } - - /** going out of scope - all execution paths end */ - void end(const std::list &checks, const Token *tok) const - { - ret(checks, tok); - } -}; - - -void CheckMemoryLeakInFunction::localleaks() -{ - // Check this scope.. - CheckLocalLeaks c(this); - checkExecutionPaths(_tokenizer->tokens(), &c); -} - - - #include "checkuninitvar.h" // CheckUninitVar::analyse void CheckMemoryLeakNoVar::check() diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 6ee44071d..828008df4 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -201,9 +201,6 @@ public: /** @brief Perform checking */ void check(); - /** @brief experimental: checking via ExecutionPath */ - void localleaks(); - /** * Checking for a memory leak caused by improper realloc usage. */ diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index bbe01d27f..95d173d9c 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -27,107 +27,6 @@ extern std::ostringstream errout; -class TestLocalLeaks : private TestFixture -{ -public: - TestLocalLeaks() : TestFixture("TestLocalLeaks") - { } - -private: - void run() - { - TEST_CASE(test1); - TEST_CASE(test2); - TEST_CASE(test3); - TEST_CASE(test4); - TEST_CASE(test5); - } - - void check(const char code[]) - { - // Clear the error buffer.. - errout.str(""); - - Settings settings; - - // Tokenize.. - Tokenizer tokenizer(&settings, this); - std::istringstream istr(code); - tokenizer.tokenize(istr, "test.cpp"); - tokenizer.setVarId(); - tokenizer.simplifyTokenList(); - - // Check for memory leaks.. - CheckMemoryLeakInFunction checkMemoryLeak(&tokenizer, &settings, this); - checkMemoryLeak.localleaks(); - } - - void test1() - { - check("void foo()\n" - "{\n" - " char *p = new char[100];\n" - "}\n"); - ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str()); - } - - void test2() - { - check("void foo()\n" - "{\n" - " char *p = new char[100];\n" - " delete [] p;\n" - "}\n"); - ASSERT_EQUALS("", errout.str()); - } - - void test3() - { - check("void foo(int x)\n" - "{\n" - " char *p = 0;\n" - " if (x == 1)\n" - " p = new char[100];\n" - " if (x == 2)\n" - " delete [] p;\n" - "}\n"); - TODO_ASSERT_EQUALS("[test.cpp:8]: (error) Memory leak: p\n", errout.str()); - ASSERT_EQUALS("", errout.str()); - } - - void test4() - { - check("void foo(int x)\n" - "{\n" - " char *p = 0;\n" - " if (x == 1)\n" - " p = new char[100];\n" - " if (x == 1)\n" - " delete [] p;\n" - "}\n"); - ASSERT_EQUALS("", errout.str()); - } - - void test5() //#ticket 1879 - { - check("void test()\n" - "{\n" - " int *a = new int[10];\n" - " try\n" - " {\n" - " }\n" - " catch(...)\n" - " {\n" - " }\n" - "}\n"); - ASSERT_EQUALS("[test.cpp:10]: (error) Memory leak: a\n",errout.str()); - } -}; - -static TestLocalLeaks testLocalLeaks; - - - class TestMemleak : private TestFixture { public: