diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index c4843420b..21b56a754 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -109,7 +109,7 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType(const To if (Token::Match(tok2, "new %type% [")) return NewArray; - if (Token::simpleMatch(tok2, "fopen (")) + if (Token::Match(tok2, "fopen|tmpfile (")) return File; if (Token::simpleMatch(tok2, "popen (")) diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 429e089f0..c677e93ba 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -214,6 +214,7 @@ private: TEST_CASE(stdstring); TEST_CASE(strndup_function); + TEST_CASE(tmpfile_function); TEST_CASE(fcloseall_function); TEST_CASE(file_functions); @@ -2186,6 +2187,45 @@ private: ASSERT_EQUALS("[test.cpp:4]: (error) Memory leak: out\n", errout.str()); } + void tmpfile_function() + { + check("void f()\n" + "{\n" + " FILE *f = tmpfile();\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4]: (error) Resource leak: f\n", errout.str()); + + check("void f()\n" + "{\n" + " FILE *f = tmpfile();\n" + " if (!f)\n" + " return;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:6]: (error) Resource leak: f\n", errout.str()); + + check("void f()\n" + "{\n" + " FILE *f = tmpfile();\n" + " fclose(f);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f()\n" + "{\n" + " FILE *f = tmpfile();\n" + " if (!f)\n" + " return;\n" + " fclose(f);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("FILE *f()\n" + "{\n" + " return tmpfile();\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + void fcloseall_function() { check("void f()\n" @@ -2194,6 +2234,13 @@ private: " fcloseall();\n" "}\n"); ASSERT_EQUALS(std::string(""), errout.str()); + + check("void f()\n" + "{\n" + " FILE *f = tmpfile();\n" + " fcloseall();\n" + "}\n"); + ASSERT_EQUALS(std::string(""), errout.str()); } void opendir_function()