Skip to content

Commit 44a66e6

Browse files
committed
Fixed danmar#1416 (false negative resource leak when calling fdopen)
1 parent 36f4431 commit 44a66e6

3 files changed

Lines changed: 38 additions & 32 deletions

File tree

cfg/posix.cfg

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,31 @@
88
<function name="mkdtemp"> <noreturn>false</noreturn> <arg nr="1"><not-uninit/><not-null/></arg> <leak-ignore/> </function>
99
<function name="mktemp"> <noreturn>false</noreturn> <arg nr="1"><not-uninit/><not-null/></arg> <leak-ignore/> </function>
1010
<function name="getcwd">
11-
<noreturn>false</noreturn>
12-
<arg nr="1"><not-null/></arg>
13-
<arg nr="2"><not-uninit/><not-null/></arg>
14-
<leak-ignore/>
15-
</function>
11+
<noreturn>false</noreturn>
12+
<arg nr="1"><not-null/></arg>
13+
<arg nr="2"><not-uninit/><not-null/></arg>
14+
<leak-ignore/>
15+
</function>
1616
<function name="mkdir">
17-
<noreturn>false</noreturn>
18-
<arg nr="1"><not-uninit/><not-null/></arg>
19-
<arg nr="2"><not-uninit/></arg>
20-
<leak-ignore/>
21-
</function>
17+
<noreturn>false</noreturn>
18+
<arg nr="1"><not-uninit/><not-null/></arg>
19+
<arg nr="2"><not-uninit/></arg>
20+
<leak-ignore/>
21+
</function>
2222
<function name="rmdir"> <noreturn>false</noreturn> <arg nr="1"><not-uninit/><not-null/></arg> <leak-ignore/> </function>
2323
<function name="chdir"> <noreturn>false</noreturn> <arg nr="1"><not-uninit/><not-null/></arg> <leak-ignore/> </function>
2424
<function name="link">
25-
<noreturn>false</noreturn>
26-
<arg nr="1"><not-uninit/><not-null/></arg>
27-
<arg nr="2"><not-uninit/><not-null/></arg>
28-
<leak-ignore/>
29-
</function>
25+
<noreturn>false</noreturn>
26+
<arg nr="1"><not-uninit/><not-null/></arg>
27+
<arg nr="2"><not-uninit/><not-null/></arg>
28+
<leak-ignore/>
29+
</function>
3030
<function name="rename"> <noreturn>false</noreturn> <arg nr="1"><not-uninit/><not-null/></arg> <leak-ignore/> </function>
3131
<function name="isatty"> <noreturn>false</noreturn> <arg nr="1"><not-uninit/></arg> <leak-ignore/> </function>
3232

3333
<function name="popen"><noreturn>false</noreturn><arg nr="1"><not-null/><not-uninit/></arg><arg nr="2"><not-null/><not-uninit/></arg></function>
3434
<function name="pclose"><noreturn>false</noreturn><arg nr="1"><not-null/><not-uninit/></arg></function>
35-
35+
<function name="fdopen"><noreturn>false</noreturn><arg nr="1"><not-null/><not-uninit/></arg></function>
3636

3737
<resource>
3838
<dealloc>close</dealloc>
@@ -46,9 +46,13 @@
4646
<alloc init="true">fdopendir</alloc>
4747
</resource>
4848

49+
<resource>
50+
<dealloc>fclose</dealloc>
51+
<alloc init="true">fdopen</alloc>
52+
</resource>
53+
4954
<resource>
5055
<dealloc>pclose</dealloc>
5156
<alloc init="true">popen</alloc>
5257
</resource>
5358
</def>
54-

lib/checkmemoryleak.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
184184
if (alloctype > 0) {
185185
if (alloctype == settings1->library.dealloc("free"))
186186
return Malloc;
187+
if (alloctype == settings1->library.dealloc("fclose"))
188+
return File;
187189
return Library::ismemory(alloctype) ? OtherMem : OtherRes;
188190
}
189191
}
@@ -612,7 +614,7 @@ const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<co
612614
if (noreturn.find(tok->str()) != noreturn.end() && tok->strAt(-1) != "=")
613615
return "exit";
614616

615-
if (varid > 0 && (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No))
617+
if (varid > 0 && (getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No))
616618
return 0;
617619

618620
if (callstack.size() > 2)

test/testmemleak.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,6 @@ class TestMemleakInFunction : public TestFixture {
330330
TEST_CASE(getc_function);
331331

332332
TEST_CASE(open_function);
333-
TEST_CASE(open_fdopen);
334333
TEST_CASE(creat_function);
335334
TEST_CASE(close_function);
336335
TEST_CASE(fd_functions);
@@ -3876,19 +3875,6 @@ class TestMemleakInFunction : public TestFixture {
38763875
ASSERT_EQUALS("", errout.str());
38773876
}
38783877

3879-
void open_fdopen() {
3880-
// Ticket #2830
3881-
Settings settings;
3882-
settings.standards.posix = true;
3883-
check("void f(const char *path)\n"
3884-
"{\n"
3885-
" int fd = open(path, O_RDONLY);\n"
3886-
" FILE *f = fdopen(fd, x);\n"
3887-
" fclose(f);\n"
3888-
"}", &settings);
3889-
ASSERT_EQUALS("", errout.str());
3890-
}
3891-
38923878
void creat_function() {
38933879
Settings settings;
38943880
settings.standards.posix = true;
@@ -4267,6 +4253,20 @@ class TestMemleakInFunction : public TestFixture {
42674253
check(code2, &settings);
42684254
ASSERT_EQUALS("", errout.str());
42694255

4256+
// Ticket #2830
4257+
check("void f(const char *path) {\n"
4258+
" int fd = open(path, O_RDONLY);\n"
4259+
" FILE *f = fdopen(fd, x);\n"
4260+
" fclose(f);\n"
4261+
"}", &settings);
4262+
ASSERT_EQUALS("", errout.str());
4263+
4264+
// Ticket #1416
4265+
check("void f(void) {\n"
4266+
" FILE *f = fdopen(0, \"r\");\n"
4267+
"}", &settings);
4268+
ASSERT_EQUALS("[test.cpp:3]: (error) Resource leak: f\n", errout.str());
4269+
42704270
LOAD_LIB_2(settings.library, "gtk.cfg");
42714271

42724272
check("void f(char *a) {\n"

0 commit comments

Comments
 (0)