From 692b6b4fe008c968198e76101dc121768d52372c Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:19:45 +0100 Subject: [PATCH 1/4] Update checkmemoryleak.cpp --- lib/checkmemoryleak.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 787df56d1fe..20f68af0853 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -735,17 +735,24 @@ void CheckMemoryLeakStructMember::check() } } -bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) const +bool CheckMemoryLeakStructMember::isMalloc(const Variable* variable) const { if (!variable) return false; const int declarationId(variable->declarationId()); bool alloc = false; - for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) { + 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; } From 8d5e72de422cf58cec363749051cbb16d852ccfe Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:21:21 +0100 Subject: [PATCH 2/4] Update testmemleak.cpp --- test/testmemleak.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) 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" From da2ad8d2fdb8a3cfc7fbe07cfeb888d26ff815d8 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:26:39 +0100 Subject: [PATCH 3/4] Update checkmemoryleak.cpp --- lib/checkmemoryleak.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 20f68af0853..c3354ceb8ec 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -749,7 +749,7 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable* variable) const 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()) { + (Token::simpleMatch(tok3, "new") && tok3->isCpp())) { alloc = true; } } From bff0296678b197263f02efcdfee68845e5ceda52 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 19 Nov 2025 19:10:57 +0100 Subject: [PATCH 4/4] Update checkmemoryleak.cpp --- lib/checkmemoryleak.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index c3354ceb8ec..024c2b5822d 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -735,13 +735,13 @@ void CheckMemoryLeakStructMember::check() } } -bool CheckMemoryLeakStructMember::isMalloc(const Variable* variable) const +bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) const { if (!variable) return false; const int declarationId(variable->declarationId()); bool alloc = false; - for (const Token* tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) { + 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% =", declarationId)) {