diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index 5d22da1ac..54236179f 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -543,13 +543,14 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const Va } if (Token::Match(arg, "%var% [-,)] !!.") || Token::Match(arg, "& %var%")) { - // goto variable if (arg->str() == "&") arg = arg->next(); + bool isnull = arg->hasKnownIntValue() && arg->values.front().intvalue == 0; + // Is variable allocated? - if (!af || af->arg == argNr) + if (!isnull && (!af || af->arg == argNr)) changeAllocStatus(varInfo, allocation, tok, arg); } else if (Token::Match(arg, "%name% (")) { const Library::AllocFunc* allocFunc = _settings->library.dealloc(arg); diff --git a/test/testleakautovar.cpp b/test/testleakautovar.cpp index 5af8f1238..5b9a21e3b 100644 --- a/test/testleakautovar.cpp +++ b/test/testleakautovar.cpp @@ -304,6 +304,12 @@ private: " return p;\n" "}"); ASSERT_EQUALS("[test.c:3]: (error) Returning/dereferencing 'p' after it is deallocated / released\n", errout.str()); + + check("void f(char *p) {\n" + " if (!p) free(p);\n" + " return p;\n" + "}"); + ASSERT_EQUALS("", errout.str()); } void deallocuse5() { // #4018