From 7f0a646491533878252ec05e17051f4727fc0f5e Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 24 Nov 2025 10:12:43 +0100 Subject: [PATCH 1/4] Update checkmemoryleak.cpp --- lib/checkmemoryleak.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index 024c2b5822d..d9caa9e0fc0 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -858,8 +858,15 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const vari // This struct member is allocated.. check that it is deallocated int indentlevel3 = indentlevel2; for (const Token *tok3 = tok2; tok3; tok3 = tok3->next()) { - if (tok3->str() == "{") - ++indentlevel3; + if (tok3->str() == "{") { + if (tok3->scope()->type == ScopeType::eIf) { // bailout: member checked in if condition + const Token* const condBeg = tok3->scope()->classDef->tokAt(1); + const Token* const condEnd = condBeg->link(); + if (Token::findmatch(condBeg, ". %varid%", condEnd, assignToks.first->varId())) + break; + } + ++identlevel3; + } else if (tok3->str() == "}") { if (indentlevel3 == 0) { From 59796d46e684f5e3bb576abfa17a6a81b9487632 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 24 Nov 2025 10:15:07 +0100 Subject: [PATCH 2/4] Update testmemleak.cpp --- test/testmemleak.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 6e4e6cdf875..b9a8a4e63df 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -1941,6 +1941,18 @@ class TestMemleakStructMember : public TestFixture { "[test.cpp:10:5]: (error) Resource leak: s.fd [resourceLeak]\n" "[test.cpp:16:1]: (error) Resource leak: s.fd [resourceLeak]\n", errout_str()); + + check("struct S { int fd; };\n" // #13031 + "void f() {\n" + " struct S* s = malloc(sizeof(struct S));\n" + " s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n" + " if (s->fd < 0) {\n" + " free(s);\n" + " return NULL;\n" + " }\n" + " return s;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void failedAllocation() { From eb4cd17cbe665a9b59f509bdd57e956b06d87f08 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 24 Nov 2025 10:22:20 +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 d9caa9e0fc0..d35da2e78ee 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -865,7 +865,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const vari if (Token::findmatch(condBeg, ". %varid%", condEnd, assignToks.first->varId())) break; } - ++identlevel3; + ++indentlevel3; } else if (tok3->str() == "}") { From 114bc84e4d27f8234ec9810d69e5e79e25951866 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Mon, 24 Nov 2025 12:55:36 +0100 Subject: [PATCH 4/4] Update checkmemoryleak.cpp --- lib/checkmemoryleak.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index d35da2e78ee..355b0d809d7 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -859,10 +859,9 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const vari int indentlevel3 = indentlevel2; for (const Token *tok3 = tok2; tok3; tok3 = tok3->next()) { if (tok3->str() == "{") { - if (tok3->scope()->type == ScopeType::eIf) { // bailout: member checked in if condition + if (tok3->scope()->type == ScopeType::eIf && tok3 == tok3->scope()->bodyStart) { // bailout: member checked in if condition const Token* const condBeg = tok3->scope()->classDef->tokAt(1); - const Token* const condEnd = condBeg->link(); - if (Token::findmatch(condBeg, ". %varid%", condEnd, assignToks.first->varId())) + if (Token::findmatch(condBeg, ". %varid%", condBeg->link(), assignToks.first->varId())) break; } ++indentlevel3;