Skip to content

Commit 5374cd3

Browse files
Refs #13031 Fix FN resourceLeak with cast (danmar#7973)
1 parent 1aefbab commit 5374cd3

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

lib/checkmemoryleak.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,15 @@ bool CheckMemoryLeakStructMember::isMalloc(const Variable *variable) const
744744
for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->bodyEnd; tok2 = tok2->next()) {
745745
if (Token::Match(tok2, "= %varid% [;=]", declarationId))
746746
return false;
747-
if (Token::Match(tok2, "%varid% = %name% (", declarationId) && mSettings->library.getAllocFuncInfo(tok2->tokAt(2)))
748-
alloc = true;
747+
if (Token::Match(tok2, "%varid% =", declarationId)) {
748+
const Token* tok3 = tok2->tokAt(1)->astOperand2();
749+
while (tok3 && tok3->isCast())
750+
tok3 = tok3->astOperand2() ? tok3->astOperand2() : tok3->astOperand1();
751+
if ((tok3 && Token::Match(tok3->tokAt(-1), "%name% (") && mSettings->library.getAllocFuncInfo(tok3->tokAt(-1))) ||
752+
(Token::simpleMatch(tok3, "new") && tok3->isCpp())) {
753+
alloc = true;
754+
}
755+
}
749756
}
750757
return alloc;
751758
}

test/testmemleak.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1673,6 +1673,7 @@ class TestMemleakStructMember : public TestFixture {
16731673
TEST_CASE(assign2);
16741674
TEST_CASE(assign3);
16751675
TEST_CASE(assign4); // #11019
1676+
TEST_CASE(assign5);
16761677

16771678
// Failed allocation
16781679
TEST_CASE(failedAllocation);
@@ -1919,6 +1920,29 @@ class TestMemleakStructMember : public TestFixture {
19191920
ASSERT_EQUALS("", errout_str());
19201921
}
19211922

1923+
void assign5() {
1924+
check("struct S { int fd; };\n"
1925+
"void f() {\n"
1926+
" struct S* s = (struct S*)malloc(sizeof(struct S));\n"
1927+
" s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n"
1928+
" free(s);\n"
1929+
"}\n"
1930+
"void g() {\n"
1931+
" struct S* s = static_cast<struct S*>(malloc(sizeof(struct S)));\n"
1932+
" s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n"
1933+
" free(s);\n"
1934+
"}\n"
1935+
"void h() {\n"
1936+
" S* s = new S;\n"
1937+
" s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n"
1938+
" delete s;\n"
1939+
"}\n");
1940+
ASSERT_EQUALS("[test.cpp:5:5]: (error) Resource leak: s.fd [resourceLeak]\n"
1941+
"[test.cpp:10:5]: (error) Resource leak: s.fd [resourceLeak]\n"
1942+
"[test.cpp:16:1]: (error) Resource leak: s.fd [resourceLeak]\n",
1943+
errout_str());
1944+
}
1945+
19221946
void failedAllocation() {
19231947
check("static struct ABC * foo()\n"
19241948
"{\n"

0 commit comments

Comments
 (0)