From e068979d620ff76494089c5b5710e55c343454e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 24 Apr 2010 22:24:03 +0200 Subject: [PATCH] Fixed #1440 (false negative: memory leak (function parameters)) --- lib/checkmemoryleak.cpp | 21 +++++++++++++++++++-- lib/checkmemoryleak.h | 5 +++-- test/testmemleak.cpp | 12 ++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index b005e65a8..ba961f5c3 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2108,11 +2108,27 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string // Checks for memory leaks inside function.. //--------------------------------------------------------------------------- -void CheckMemoryLeakInFunction::parseFunctionScope(const Token *tok, const bool classmember) +void CheckMemoryLeakInFunction::parseFunctionScope(const Token *tok, const Token *tok1, const bool classmember) { // Check locking/unlocking of global resources.. checkScope(tok->next(), "", 0, classmember, 1); + // Locate parameters and check their usage.. + for (const Token *tok2 = tok1; tok2; tok2 = tok2->next()) + { + if (tok2 == tok) + break; + if (tok2->str() == ")") + break; + if (Token::Match(tok2, "[(,] %type% * %var% [,)]") && tok2->next()->isStandardType()) + { + const std::string varname(tok2->strAt(3)); + const unsigned int varid = tok2->tokAt(3)->varId(); + const unsigned int sz = _tokenizer->sizeOfType(tok->next()); + checkScope(tok->next(), varname, varid, classmember, sz); + } + } + // Locate variable declarations and check their usage.. unsigned int indentlevel = 0; do @@ -2187,9 +2203,10 @@ void CheckMemoryLeakInFunction::check() // Found a function scope if (Token::Match(tok, ") const| {")) { + const Token * const tok1 = tok->link(); while (tok->str() != "{") tok = tok->next(); - parseFunctionScope(tok, classmember); + parseFunctionScope(tok, tok1, classmember); tok = tok->link(); continue; } diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 67d7e1cb2..17e345537 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -193,10 +193,11 @@ public: /** * @brief %Check all variables in function scope - * @param tok The first '{' token of the function scope + * @param tok The first '{' token of the function body + * @param tok1 The '(' token in the function declaration * @param classmember Is this function a class member? */ - void parseFunctionScope(const Token *tok, const bool classmember); + void parseFunctionScope(const Token *tok, const Token *tok1, const bool classmember); /** * @brief %Check if there is a "p = foo(p, .." and foo returns the argument (p) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 60b2947bc..29cc8bc0b 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -381,6 +381,9 @@ private: TEST_CASE(knownFunctions); TEST_CASE(same_function_name); + + // #1440 - Check function parameters also.. + TEST_CASE(functionParameter); } @@ -2688,6 +2691,15 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); } + + void functionParameter() + { + check("void a(char *p)\n" + "{\n" + " p = malloc(100);\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: p\n", errout.str()); + } }; static TestMemleakInFunction testMemleakInFunction;