diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index c5ec210d1..9d984c595 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -384,14 +384,14 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list if (parlevel == 0 && tok->str() == ";") addtoken(";"); - if (Token::Match(tok, std::string("[(;{}] " + varnameStr + " =").c_str())) + if (Token::Match(tok->previous(), std::string("[(;{}] " + varnameStr + " =").c_str())) { - AllocType alloc = GetAllocationType(tok->tokAt(3)); + AllocType alloc = GetAllocationType(tok->tokAt(2)); bool realloc = false; if (alloc == No) { - alloc = GetReallocationType(tok->tokAt(3)); + alloc = GetReallocationType(tok->tokAt(2)); if (alloc != No) { addtoken("realloc"); @@ -403,9 +403,9 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list // If "--all" hasn't been given, don't check classes.. if (alloc == New) { - if (Token::Match(tok->tokAt(3), "new %type% [(;]")) + if (Token::Match(tok->tokAt(2), "new %type% [(;]")) { - if (isclass(tok->tokAt(4))) + if (isclass(tok->tokAt(3))) { if (_settings._showAll) all = true; @@ -433,7 +433,7 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list alloctype = alloc; } - else if (MatchFunctionsThatReturnArg(tok, std::string(varname))) + else if (MatchFunctionsThatReturnArg(tok->previous(), std::string(varname))) { addtoken("use"); } @@ -1029,10 +1029,11 @@ void CheckMemoryLeakClass::simplifycode(Token *tok) done = false; } - // Reduce "[;{}] alloc ; dealloc ; !!dealloc" => "[;{}]" - if (Token::Match(tok2, "[;{}] alloc ; dealloc ; !!dealloc")) + // malloc - realloc => alloc ; dealloc ; alloc ; + // Reduce "[;{}] alloc ; dealloc ; alloc ;" => "[;{}] alloc ;" + if (Token::Match(tok2, "[;{}] alloc ; dealloc ; alloc ;")) { - erase(tok2, tok2->tokAt(5)); + erase(tok2->next(), tok2->tokAt(6)); done = false; } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 03e710750..bf1c6f46f 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -71,6 +71,8 @@ private: TEST_CASE(simple9); // Bug 2435468 - member function "free" TEST_CASE(simple10); // fclose in a if condition + TEST_CASE(alloc_alloc_1); + TEST_CASE(use1); TEST_CASE(use2); @@ -300,6 +302,20 @@ private: + void alloc_alloc_1() + { + check("void foo()\n" + "{\n" + " char *str;\n" + " str = new char[10];\n" + " str = new char[20];\n" + " delete [] str;\n" + "}\n"); + ASSERT_EQUALS(std::string("[test.cpp:5]: (error) Memory leak: str\n"), errout.str()); + } + + + @@ -840,7 +856,7 @@ private: " while (!str);\n" " return str;\n" "}\n"); - ASSERT_EQUALS(std::string("[test.cpp:5]: (error) Memory leak: str\n"), errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:6]: (error) Memory leak: str\n"), errout.str()); } @@ -1013,7 +1029,7 @@ private: " }\n" " delete [] p;\n" "}\n", false); - ASSERT_EQUALS(std::string("[test.cpp:6]: (error) Mismatching allocation and deallocation: p\n"), errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:7]: (error) Mismatching allocation and deallocation: p\n"), errout.str()); } @@ -1522,7 +1538,6 @@ private: " char *a = (char *)malloc(10);\n" " a = realloc(a, 100);\n" "}\n"); - ASSERT_EQUALS(std::string("[test.cpp:5]: (error) Memory leak: a\n"), errout.str()); } @@ -1548,7 +1563,7 @@ private: " free(a);\n" "}\n"); - ASSERT_EQUALS(std::string("[test.cpp:3]: (error) Memory leak: a\n"), errout.str()); + ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Memory leak: a\n"), errout.str()); check("void foo()\n" "{\n" @@ -1764,15 +1779,13 @@ private: void strcat_result_assignment() { - check("#include \n" - "#include \n" - "int main()\n" + check("void foo()\n" "{\n" - "char *p = malloc(10);\n" - "p[0] = 0;\n" - "p = strcat( p, \"a\" );\n" - "free( p );\n" - "return 0;\n" + " char *p = malloc(10);\n" + " p[0] = 0;\n" + " p = strcat( p, \"a\" );\n" + " free( p );\n" + " return 0;\n" "}"); ASSERT_EQUALS(std::string(""), errout.str()); }