diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index e4fe9462d..d10f05a0a 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -561,6 +561,24 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, varInfo->clear(); } + // delete + else if (mTokenizer->isCPP() && tok->str() == "delete") { + const bool arrayDelete = Token::simpleMatch(tok->next(), "[ ]"); + if (arrayDelete) + tok = tok->tokAt(3); + else + tok = tok->next(); + if (tok->str() == "(") + tok = tok->next(); + while (Token::Match(tok, "%name% ::|.")) + tok = tok->tokAt(2); + const bool isnull = tok->hasKnownIntValue() && tok->values().front().intvalue == 0; + if (!isnull && tok->varId() && tok->strAt(1) != "[") { + const VarInfo::AllocInfo allocation(arrayDelete ? NEW_ARRAY : NEW, VarInfo::DEALLOC); + changeAllocStatus(varInfo, allocation, tok, tok); + } + } + // Function call.. else if (isFunctionCall(ftok)) { const Token * openingPar = isFunctionCall(ftok); @@ -587,22 +605,6 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, continue; } - // delete - else if (mTokenizer->isCPP() && tok->str() == "delete") { - const bool arrayDelete = (tok->strAt(1) == "["); - if (arrayDelete) - tok = tok->tokAt(3); - else - tok = tok->next(); - while (Token::Match(tok, "%name% ::|.")) - tok = tok->tokAt(2); - const bool isnull = tok->hasKnownIntValue() && tok->values().front().intvalue == 0; - if (!isnull && tok->varId() && tok->strAt(1) != "[") { - const VarInfo::AllocInfo allocation(arrayDelete ? NEW_ARRAY : NEW, VarInfo::DEALLOC); - changeAllocStatus(varInfo, allocation, tok, tok); - } - } - // goto => weird execution path else if (tok->str() == "goto") { varInfo->clear(); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 349f79056..680b01a28 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -81,6 +81,7 @@ private: // TODO TEST_CASE(deallocuse5); // #4018: FP. free(p), p = 0; TEST_CASE(deallocuse6); // #4034: FP. x = p = f(); TEST_CASE(deallocuse7); // #6467, #6469, #6473 + TEST_CASE(deallocuse8); // #1765 TEST_CASE(doublefree1); TEST_CASE(doublefree2); @@ -561,6 +562,15 @@ private: ASSERT_EQUALS("", errout.str()); } + void deallocuse8() { // #1765 + check("void f() {\n" + " int *ptr = new int;\n" + " delete(ptr);\n" + " *ptr = 0;\n" + "}", true); + ASSERT_EQUALS("[test.cpp:4]: (error) Dereferencing 'ptr' after it is deallocated / released\n", errout.str()); + } + void doublefree1() { // #3895 check("void f(char *p) {\n" " if (x)\n"