diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 72e58f20c..dcb203360 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -3101,7 +3101,8 @@ void CheckMemoryLeakStructMember::check() else if (tok3->str() == "return") { // Returning from function without deallocating struct member? - if (!Token::Match(tok3, "return %varid% ;", structid)) + if (!Token::Match(tok3, "return %varid% ;", structid) && + !Token::Match(tok3, "return & %varid% .", structid)) { memoryLeak(tok3, (vartok->str() + "." + tok2->strAt(2)).c_str(), Malloc); } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 36978ff79..4cebd567f 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -4206,7 +4206,8 @@ private: TEST_CASE(goto_); // Don't report errors if the struct is returned - TEST_CASE(ret); + TEST_CASE(ret1); + TEST_CASE(ret2); // assignments TEST_CASE(assign); @@ -4284,7 +4285,7 @@ private: ASSERT_EQUALS("", errout.str()); } - void ret() + void ret1() { check("static ABC * foo()\n" "{\n" @@ -4301,6 +4302,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void ret2() + { + check("static ABC * foo()\n" + "{\n" + " struct ABC *abc = malloc(sizeof(struct ABC));\n" + " abc->a = malloc(10);\n" + " return &abc->self;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void assign() { check("static void foo()\n"