diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 787df56d1fe..024c2b5822d 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -744,8 +744,15 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) const for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) { if (Token::Match(tok2, "= %varid% [;=]", declarationId)) return false; - if (Token::Match(tok2, "%varid% = %name% (", declarationId) && mSettings->library.getAllocFuncInfo(tok2->tokAt(2))) - alloc = true; + if (Token::Match(tok2, "%varid% =", declarationId)) { + const Token* tok3 = tok2->tokAt(1)->astOperand2(); + while (tok3 && tok3->isCast()) + tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1(); + if ((tok3 && Token::Match(tok3->tokAt(-1), "%name% (") && mSettings->library.getAllocFuncInfo(tok3->tokAt(-1))) || + (Token::simpleMatch(tok3, "new") && tok3->isCpp())) { + alloc = true; + } + } } return alloc; } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index d93323c29ef..6e4e6cdf875 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -1673,6 +1673,7 @@ class TestMemleakStructMember : public TestFixture { TEST_CASE(assign2); TEST_CASE(assign3); TEST_CASE(assign4); // #11019 + TEST_CASE(assign5); // Failed allocation TEST_CASE(failedAllocation); @@ -1919,6 +1920,29 @@ class TestMemleakStructMember : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void assign5() { + check("struct S { int fd; };\n" + "void f() {\n" + " struct S* s = (struct S*)malloc(sizeof(struct S));\n" + " s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n" + " free(s);\n" + "}\n" + "void g() {\n" + " struct S* s = static_cast(malloc(sizeof(struct S)));\n" + " s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n" + " free(s);\n" + "}\n" + "void h() {\n" + " S* s = new S;\n" + " s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n" + " delete s;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:5:5]: (error) Resource leak: s.fd [resourceLeak]\n" + "[test.cpp:10:5]: (error) Resource leak: s.fd [resourceLeak]\n" + "[test.cpp:16:1]: (error) Resource leak: s.fd [resourceLeak]\n", + errout_str()); + } + void failedAllocation() { check("static struct ABC * foo()\n" "{\n"