Skip to content

Commit d1e4660

Browse files
Fix #13031 FP resourceLeak with struct (#7982)
1 parent f077ec4 commit d1e4660

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

lib/checkmemoryleak.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -858,8 +858,14 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable* const vari
858858
// This struct member is allocated.. check that it is deallocated
859859
int indentlevel3 = indentlevel2;
860860
for (const Token *tok3 = tok2; tok3; tok3 = tok3->next()) {
861-
if (tok3->str() == "{")
861+
if (tok3->str() == "{") {
862+
if (tok3->scope()->type == ScopeType::eIf && tok3 == tok3->scope()->bodyStart) { // bailout: member checked in if condition
863+
const Token* const condBeg = tok3->scope()->classDef->tokAt(1);
864+
if (Token::findmatch(condBeg, ". %varid%", condBeg->link(), assignToks.first->varId()))
865+
break;
866+
}
862867
++indentlevel3;
868+
}
863869

864870
else if (tok3->str() == "}") {
865871
if (indentlevel3 == 0) {

test/testmemleak.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1941,6 +1941,18 @@ class TestMemleakStructMember : public TestFixture {
19411941
"[test.cpp:10:5]: (error) Resource leak: s.fd [resourceLeak]\n"
19421942
"[test.cpp:16:1]: (error) Resource leak: s.fd [resourceLeak]\n",
19431943
errout_str());
1944+
1945+
check("struct S { int fd; };\n" // #13031
1946+
"void f() {\n"
1947+
" struct S* s = malloc(sizeof(struct S));\n"
1948+
" s->fd = open(\"abc\", O_RDWR | O_NOCTTY);\n"
1949+
" if (s->fd < 0) {\n"
1950+
" free(s);\n"
1951+
" return NULL;\n"
1952+
" }\n"
1953+
" return s;\n"
1954+
"}\n");
1955+
ASSERT_EQUALS("", errout_str());
19441956
}
19451957

19461958
void failedAllocation() {

0 commit comments

Comments
 (0)