From 2e439d8cea42809181472501a24819eeb55d6d19 Mon Sep 17 00:00:00 2001 From: Nicolas Le Cam Date: Fri, 2 Jan 2009 00:05:08 +0000 Subject: [PATCH] Memory leak : Completly fix false positive when using callbacks (Bug 2458510) --- checkmemoryleak.cpp | 26 ++++++++++++++++++-------- testmemleak.cpp | 11 +++++++++++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/checkmemoryleak.cpp b/checkmemoryleak.cpp index 05a0ddd32..0a830c7d2 100644 --- a/checkmemoryleak.cpp +++ b/checkmemoryleak.cpp @@ -587,17 +587,27 @@ TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, std::list } // Callback.. - if ( TOKEN::Match(tok, "( * %var% ) (") || - TOKEN::Match(tok, "( %var% ) (") ) + bool matchFirst; + if ( (matchFirst = TOKEN::Match(tok, "( %var%")) || + TOKEN::Match(tok, "( * %var%") ) { - for ( const TOKEN *tok2 = tok->tokAt(4); tok2; tok2 = tok2->next() ) + int tokIdx = matchFirst ? 2 : 3; + + while ( TOKEN::simpleMatch(tok->tokAt(tokIdx), ".") && + TOKEN::Match(tok->tokAt(tokIdx + 1), "%var%") ) + tokIdx += 2; + + if ( TOKEN::simpleMatch(tok->tokAt(tokIdx), ") (") ) { - if ( TOKEN::Match(tok2, "[;{]") ) - break; - else if ( tok2->str() == varname ) + for ( const TOKEN *tok2 = tok->tokAt(tokIdx + 2); tok2; tok2 = tok2->next() ) { - addtoken("use"); - break; + if ( TOKEN::Match(tok2, "[;{]") ) + break; + else if ( tok2->str() == varname ) + { + addtoken("use"); + break; + } } } } diff --git a/testmemleak.cpp b/testmemleak.cpp index edca32310..5c43d08dc 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -126,6 +126,7 @@ private: TEST_CASE( func8 ); // Using callback TEST_CASE( func9 ); // Embedding the function call in a if-condition TEST_CASE( func10 ); // Bug 2458510 - Function pointer + TEST_CASE( func11 ); // Bug 2458510 - Function pointer TEST_CASE( class1 ); TEST_CASE( class2 ); @@ -1012,6 +1013,16 @@ private: ASSERT_EQUALS( std::string(""), errout.str() ); } + void func11() + { + check( "static void f(struct1 *s1)\n" + "{\n" + " char *c = malloc(50);\n" + " (s1->fnc)(c);\n" + "}\n" ); + ASSERT_EQUALS( std::string(""), errout.str() ); + } + /* void func3()