From c46c4c50e916b4863f65100e5b6f9b8c65fd18cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 4 Feb 2009 06:11:36 +0000 Subject: [PATCH] memory leak: fixed ticket #9 --- src/checkmemoryleak.cpp | 14 ++++++++------ src/checkmemoryleak.h | 11 ++++++++++- test/testmemleak.cpp | 15 ++++++++++++++- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index f84755fa2..891572bec 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -308,7 +308,7 @@ bool CheckMemoryLeakClass::MatchFunctionsThatReturnArg(const Token *tok, const s return Token::Match(tok, std::string("; " + varname + " = strcat|memcpy|memmove|strcpy ( " + varname + " ,").c_str()); } -bool CheckMemoryLeakClass::notvar(const Token *tok, const char *varnames[]) +bool CheckMemoryLeakClass::notvar(const Token *tok, const char *varnames[], bool endpar) { std::string varname; for (int i = 0; varnames[i]; i++) @@ -319,10 +319,12 @@ bool CheckMemoryLeakClass::notvar(const Token *tok, const char *varnames[]) varname += varnames[i]; } - return bool(Token::Match(tok, std::string("! " + varname + " [;)&|]").c_str()) || - Token::simpleMatch(tok, std::string("! ( " + varname + " )").c_str()) || - Token::Match(tok, std::string("0 == " + varname + " [;)&|]").c_str()) || - Token::simpleMatch(tok, std::string(varname + " == 0").c_str())); + const std::string end(endpar ? " )" : " [;)&|]"); + + return bool(Token::Match(tok, std::string("! " + varname + end).c_str()) || + Token::simpleMatch(tok, std::string("! ( " + varname + " )" + end).c_str()) || + Token::Match(tok, std::string("0 == " + varname + end).c_str()) || + Token::simpleMatch(tok, std::string(varname + " == 0" + end).c_str())); } Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list callstack, const char varname[], AllocType &alloctype, AllocType &dealloctype, bool classmember, bool &all) @@ -485,7 +487,7 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list while (tok->str() != ")") tok = tok->next(); } - else if (Token::simpleMatch(tok, "if (") && notvar(tok->tokAt(2), varnames)) + else if (Token::simpleMatch(tok, "if (") && notvar(tok->tokAt(2), varnames, true)) { addtoken("if(!var)"); } diff --git a/src/checkmemoryleak.h b/src/checkmemoryleak.h index b9e7c74cc..16909529a 100644 --- a/src/checkmemoryleak.h +++ b/src/checkmemoryleak.h @@ -89,7 +89,16 @@ private: * memory by calling Tokenizer::deleteTokens(returnValue); */ Token *getcode(const Token *tok, std::list callstack, const char varname[], AllocType &alloctype, AllocType &dealloctype, bool classmember, bool &all); - bool notvar(const Token *tok, const char *varnames[]); + + /** + * Check if there is a "!var" match inside a condition + * @param tok first token to match + * @param varnames the varname + * @param endpar if this is true the "!var" must be followed by ")" + * @return true if match + */ + bool notvar(const Token *tok, const char *varnames[], bool endpar = false); + bool MatchFunctionsThatReturnArg(const Token *tok, const std::string &varname); void MemoryLeak(const Token *tok, const char varname[], AllocType alloctype, bool all); void MismatchError(const Token *Tok1, const std::list &callstack, const char varname[]); diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index d98393f71..b3ffaa302 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -94,6 +94,7 @@ private: TEST_CASE(if8); // Bug 2458532 // TODO TEST_CASE( if9 ); // if (realloc) TEST_CASE(if10); // else if (realloc) + TEST_CASE(if11); TEST_CASE(forwhile1); TEST_CASE(forwhile2); @@ -629,7 +630,19 @@ private: ASSERT_EQUALS(std::string(""), errout.str()); } - + void if11() + { + check("void foo()\n" + "{\n" + " int *x = new int[10];\n" + " if (x == 0 || aa)\n" + " {\n" + " return 1;\n" + " }\n" + " delete [] x;\n" + "}\n", true); + ASSERT_EQUALS(std::string("[test.cpp:6]: (always) Memory leak: x\n"), errout.str()); + }