From 80feb8697d03e3479ccc5fe5bf8e65f57e59b172 Mon Sep 17 00:00:00 2001 From: PKEuS Date: Thu, 29 Jan 2015 21:26:06 +0100 Subject: [PATCH] Fixed false positives #6473 and #6469 --- lib/checkleakautovar.cpp | 7 ++++++- test/testleakautovar.cpp | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index a94bb6976..3fa6b52ca 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -150,6 +150,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, // Parse all tokens const Token * const endToken = startToken->link(); for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) { + if (!tok->scope()->isExecutable()) + tok = tok->scope()->classEnd; + // Deallocation and then dereferencing pointer.. if (tok->varId() > 0) { const std::map::iterator var = alloctype.find(tok->varId()); @@ -181,7 +184,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, if (!tok || tok == endToken) break; - // parse statement + // parse statement, skip to last member + while (Token::Match(tok, "%var% ::|. %var% !!(")) + tok = tok->tokAt(2); // assignment.. if (tok->varId() && Token::Match(tok, "%var% =")) { diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 1b09d382c..802cc8d91 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -53,7 +53,7 @@ private: TEST_CASE(deallocuse4); TEST_CASE(deallocuse5); // #4018: FP. free(p), p = 0; TEST_CASE(deallocuse6); // #4034: FP. x = p = f(); - TEST_CASE(deallocuse7); // #6467 + TEST_CASE(deallocuse7); // #6467, #6469, #6473 TEST_CASE(doublefree1); TEST_CASE(doublefree2); @@ -316,7 +316,7 @@ private: ASSERT_EQUALS("", errout.str()); } - void deallocuse7() { // #6467 + void deallocuse7() { // #6467, #6469, #6473 check("struct Foo { int* ptr; };\n" "void f(Foo* foo) {\n" " delete foo->ptr;\n" @@ -330,6 +330,27 @@ private: " x = *foo->ptr; \n" "}", true); ASSERT_EQUALS("[test.cpp:4]: (error) Dereferencing 'ptr' after it is deallocated / released\n", errout.str()); + + check("void parse() {\n" + " struct Buf {\n" + " Buf(uint32_t len) : m_buf(new uint8_t[len]) {}\n" + " ~Buf() { delete[]m_buf; }\n" + " uint8_t *m_buf;\n" + " };\n" + "}", true); + ASSERT_EQUALS("", errout.str()); + + check("struct Foo {\n" + " Foo();\n" + " Foo* ptr;\n" + " void func();\n" + "};\n" + "void bar(Foo* foo) {\n" + " delete foo->ptr;\n" + " foo->ptr = new Foo;\n" + " foo->ptr->func();\n" + "}", true); + ASSERT_EQUALS("", errout.str()); } void doublefree1() { // #3895