From 1aa724921889a2e21c29bb86e635ed0e532661ff Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 20 May 2026 13:44:44 +0200 Subject: [PATCH 1/3] Update checkmemoryleak.cpp --- lib/checkmemoryleak.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/checkmemoryleak.cpp b/lib/checkmemoryleak.cpp index b2f97693cd6..816c0347c85 100644 --- a/lib/checkmemoryleak.cpp +++ b/lib/checkmemoryleak.cpp @@ -1022,10 +1022,8 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) const Token* tok2 = tok->next()->astParent(); while (tok2 && (tok2->isCast() || Token::Match(tok2, "?|:"))) tok2 = tok2->astParent(); - if (Token::Match(tok2, "%assign%")) // TODO: check if function returns allocated resource - continue; - if (Token::simpleMatch(tok->astTop(), "return")) - continue; + const bool hasAssign = Token::Match(tok2, "%assign%"); + const bool hasReturn = Token::simpleMatch(tok->astTop(), "return"); const std::string& functionName = tok->str(); if ((tok->isCpp() && functionName == "delete") || @@ -1037,6 +1035,12 @@ void CheckMemoryLeakNoVar::checkForUnreleasedInputArgument(const Scope *scope) if (!tok->isKeyword() && !tok->function() && !mSettings->library.isLeakIgnore(functionName)) continue; + if ((hasAssign || hasReturn) && !tok->function()) { + const std::string& ret = mSettings->library.returnValueType(tok); + if (ret.empty() || endsWith(ret, "*")) + continue; + } + const std::vector args = getArguments(tok); int argnr = -1; for (const Token* arg : args) { From ee311fc3ab734b45725b47d919b7c7bb42001bcf Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 20 May 2026 13:46:04 +0200 Subject: [PATCH 2/3] Update testmemleak.cpp --- test/testmemleak.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 1ed88120886..8b1c1d2302c 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2603,6 +2603,17 @@ class TestMemleakNoVar : public TestFixture { " a.g(new int);\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("int f() {\n" // #11184 + " return strlen(new char[4]{});\n" + "}\n" + "int g() {\n" + " int i = strlen(new char[4]{});\n" + " return i;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:2:19]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n" + "[test.cpp:5:20]: (error) Allocation with new, strlen doesn't release it. [leakNoVarFunctionCall]\n", + errout_str()); } void missingAssignment() { From bc5dece1c1eeacfc0e1640ebafb0169024a30726 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Wed, 20 May 2026 14:46:05 +0200 Subject: [PATCH 3/3] Format --- test/testmemleak.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 8b1c1d2302c..d7198b37868 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -2604,7 +2604,7 @@ class TestMemleakNoVar : public TestFixture { "}\n"); ASSERT_EQUALS("", errout_str()); - check("int f() {\n" // #11184 + check("int f() {\n" // #11184 " return strlen(new char[4]{});\n" "}\n" "int g() {\n"