From 9ffd06ff5e27229d6a1b5c516e2f1dda7103654b Mon Sep 17 00:00:00 2001 From: Zachary Blair Date: Sun, 18 Jul 2010 23:55:39 -0700 Subject: [PATCH] Fixed #1856 (false positive: "pData" nulled but not freed upon failure) --- lib/checkmemoryleak.cpp | 27 ++++++++++++++++++++++++--- test/testmemleak.cpp | 16 ++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 21d47adf6..15365f84d 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2186,11 +2186,32 @@ void CheckMemoryLeakInFunction::checkScope(const Token *Tok1, const std::string void CheckMemoryLeakInFunction::checkReallocUsage() { const Token *tok = _tokenizer->tokens(); - for (; tok; tok = tok->next()) + while ((tok = Token::findmatch(tok, ") const| {"))) { - if (Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% ,")) + // Record the varid's of the function parameters + std::set parameterVarIds; + for (tok = tok->link(); tok && tok->str() != "{"; tok = tok->next()) { - if (tok->varId() == tok->tokAt(4)->varId()) + if (tok->varId() != 0) + parameterVarIds.insert(tok->varId()); + } + + // Search for the "var = realloc(var, 100);" pattern within this function + unsigned int indentlevel = 0; + for (tok = tok->next(); tok; tok = tok->next()) + { + if (tok->str() == "{") + ++indentlevel; + else if (tok->str() == "}") + { + if (indentlevel == 0) + break; + --indentlevel; + } + + if (Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% ,") && + tok->varId() == tok->tokAt(4)->varId() && + parameterVarIds.find(tok->varId()) == parameterVarIds.end()) { memleakUponReallocFailureError(tok, tok->str()); } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 7112cea53..07058e0ec 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -329,6 +329,7 @@ private: TEST_CASE(realloc4); TEST_CASE(realloc5); TEST_CASE(realloc6); + TEST_CASE(realloc7); TEST_CASE(assign); @@ -2012,6 +2013,21 @@ private: ASSERT_EQUALS(";;alloc;", getcode("char *buf; buf=realloc(0,100);", "buf")); } + void realloc7() + { + check("bool foo(size_t nLen, char* pData)\n" + "{\n" + " pData = (char*) realloc(pData, sizeof(char) + (nLen + 1)*sizeof(char));\n" + " if ( pData == NULL )\n" + " {\n" + " return false;\n" + " }\n" + " free(pData);\n" + " return true;\n" + "}\n", false); + ASSERT_EQUALS("", errout.str()); + } + void assign() { check("void foo()\n"