diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index c8e93a3b2..985e9a25e 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -240,7 +240,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken, if (tok->varId() > 0) { const std::map::iterator var = alloctype.find(tok->varId()); if (var != alloctype.end()) { - if (var->second == "dealloc") { + if (var->second == "dealloc" && !Token::Match(tok->previous(), "[;{},] %var% =")) { deallocUseError(tok, tok->str()); } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) { varInfo->erase(tok->varId()); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 14436c5c4..97bd72da7 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -48,6 +48,7 @@ private: TEST_CASE(deallocuse2); TEST_CASE(deallocuse3); TEST_CASE(deallocuse4); + TEST_CASE(deallocuse5); // #4018: FP. free(p), p = 0; TEST_CASE(doublefree1); TEST_CASE(doublefree2); @@ -244,6 +245,14 @@ private: ASSERT_EQUALS("[test.c:3]: (error) Returning/dereferencing 'p' after it is deallocated / released\n", errout.str()); } + void deallocuse5() { // #4018 + check("void f(char *p) {\n" + " free(p), p = 0;\n" + " *p = 0;\n" // <- Make sure pointer info is reset. It is NOT a freed pointer dereference + "}"); + ASSERT_EQUALS("", errout.str()); + } + void doublefree1() { // #3895 check("void f(char *p) {\n" " if (x)\n"