diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 6d88753ce..f262b5684 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -1345,8 +1345,22 @@ Token *CheckMemoryLeakInFunction::getcode(const Token *tok, std::list 0 && Token::Match(tok, "[=(,] & %varid% [.[,)]", varid)) { - addtoken(&rettail, tok, "&use"); + if (varid > 0 && Token::Match(tok, "[=(,] & (| %varid% [.[,)]", varid)) { + // Is variable passed to a "leak-ignore" function? + bool leakignore = false; + if (Token::Match(tok, "[(,]")) { + const Token *parent = tok; + while (parent && parent->str() != "(") + parent = parent->astParent(); + if (parent && parent->astOperand1() && parent->astOperand1()->isName()) { + const std::string &functionName = parent->astOperand1()->str(); + if (_settings->library.leakignore.find(functionName) != _settings->library.leakignore.end()) + leakignore = true; + } + } + // Not passed to "leak-ignore" function, add "&use". + if (!leakignore) + addtoken(&rettail, tok, "&use"); } } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 975acec43..da221dfe5 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -258,6 +258,7 @@ private: TEST_CASE(throw2); TEST_CASE(linux_list_1); + TEST_CASE(linux_list_2); TEST_CASE(sizeof1); @@ -2855,6 +2856,14 @@ private: ASSERT_EQUALS("", errout.str()); } + void linux_list_2() { // #5993 + check("void foo() {\n" + " struct AB *ab = malloc(sizeof(struct AB));\n" + " list_add_tail(&(ab->list));\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void sizeof1() {