From 38be7056b02366073c7771668aebac519be26826 Mon Sep 17 00:00:00 2001 From: Zachary Blair Date: Wed, 12 Jan 2011 22:33:46 -0800 Subject: [PATCH] Fixed #2434 (FP memleakOnRealloc) --- lib/checkmemoryleak.cpp | 19 +++++++++++++++---- test/testmemleak.cpp | 13 +++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index c24421cfa..5e6efda33 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -2451,14 +2451,25 @@ void CheckMemoryLeakInFunction::checkReallocUsage() } if (tok->varId() > 0 && - Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% ,") && + Token::Match(tok, "%var% = realloc|g_try_realloc ( %var% , %any% ) ;|}") && tok->varId() == tok->tokAt(4)->varId() && parameterVarIds.find(tok->varId()) == parameterVarIds.end()) { // Check that another copy of the pointer wasn't saved earlier in the function - if (!Token::findmatch(startOfFunction, "%var% = %varid% ;", tok->varId()) && - !Token::findmatch(startOfFunction, "[{};] %varid% = %var% [;=]", tok->varId())) - memleakUponReallocFailureError(tok, tok->str()); + if (Token::findmatch(startOfFunction, "%var% = %varid% ;", tok->varId()) || + Token::findmatch(startOfFunction, "[{};] %varid% = %var% [;=]", tok->varId())) + continue; + + // Check that the allocation isn't followed immediately by an 'if (!var) { error(); }' that might handle failure + if (Token::Match(tok->tokAt(9), "if ( ! %varid% ) {", tok->varId())) + { + const Token* tokEndBrace = tok->tokAt(14)->link(); + if (tokEndBrace && Token::simpleMatch(tokEndBrace->tokAt(-2), ") ;") && + Token::Match(tokEndBrace->tokAt(-2)->link()->tokAt(-2), "{|}|; %var% (")) + continue; + } + + memleakUponReallocFailureError(tok, tok->str()); } } } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 2c7503fd2..cba61fb40 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -253,6 +253,7 @@ private: TEST_CASE(realloc8); TEST_CASE(realloc9); TEST_CASE(realloc10); + TEST_CASE(realloc11); TEST_CASE(assign); @@ -2150,6 +2151,18 @@ private: ASSERT_EQUALS("", errout.str()); } + void realloc11() + { + check("void foo() {\n" + " char *p;\n" + " p = realloc(p, size);\n" + " if (!p)\n" + " error();\n" + " usep(p);\n" + "}\n", false); + ASSERT_EQUALS("", errout.str()); + } + void assign() { check("void foo()\n"