Added support to search resource leaks after opendir()/fdopendir() usage.
This commit is contained in:
parent
f5300ae56c
commit
2654a4aa54
|
@ -116,6 +116,9 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType(const To
|
|||
if (Token::simpleMatch(tok2, "popen ("))
|
||||
return Pipe;
|
||||
|
||||
if (Token::simpleMatch(tok2, "opendir (") || Token::simpleMatch(tok2, "fdopendir ("))
|
||||
return Dir;
|
||||
|
||||
// Userdefined allocation function..
|
||||
std::list<AllocFunc>::const_iterator it = _listAllocFunc.begin();
|
||||
while (it != _listAllocFunc.end())
|
||||
|
@ -193,6 +196,9 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType(const
|
|||
if (Token::simpleMatch(tok, std::string("pclose ( " + names + " )").c_str()))
|
||||
return Pipe;
|
||||
|
||||
if (Token::simpleMatch(tok, std::string("closedir ( " + names + " )").c_str()))
|
||||
return Dir;
|
||||
|
||||
return No;
|
||||
}
|
||||
//--------------------------------------------------------------------------
|
||||
|
@ -217,6 +223,11 @@ const char * CheckMemoryLeakClass::call_func(const Token *tok, std::list<const T
|
|||
Token::Match(tok, "setvbuf|setbuf|setbuffer|setlinebuf|rewind"))
|
||||
return 0;
|
||||
|
||||
// Functions to work with directories that are not allocating nor
|
||||
// deallocating memory..
|
||||
if (Token::Match(tok, "readdir|readdir_r|rewinddir|telldir|seekdir|scandir"))
|
||||
return 0;
|
||||
|
||||
// Convert functions that are not allocating nor deallocating memory..
|
||||
if (Token::Match(tok, "atoi|atof|atol|strtol|strtoul|strtod"))
|
||||
return 0;
|
||||
|
@ -306,7 +317,8 @@ const char * CheckMemoryLeakClass::call_func(const Token *tok, std::list<const T
|
|||
void CheckMemoryLeakClass::MemoryLeak(const Token *tok, const char varname[], AllocType alloctype, bool all)
|
||||
{
|
||||
if (alloctype == CheckMemoryLeakClass::File ||
|
||||
alloctype == CheckMemoryLeakClass::Pipe)
|
||||
alloctype == CheckMemoryLeakClass::Pipe ||
|
||||
alloctype == CheckMemoryLeakClass::Dir)
|
||||
resourceLeakError(tok, varname);
|
||||
else if (all)
|
||||
memleakallError(tok, varname);
|
||||
|
@ -542,7 +554,7 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list<const Token *>
|
|||
if (parlevel <= 0)
|
||||
break;
|
||||
}
|
||||
if (Token::simpleMatch(tok2, std::string("fclose ( " + varnameStr + " )").c_str()))
|
||||
if (Token::Match(tok2, std::string("fclose|closedir ( " + varnameStr + " )").c_str()))
|
||||
{
|
||||
addtoken("dealloc");
|
||||
addtoken(";");
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
private:
|
||||
|
||||
/** What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */
|
||||
enum AllocType { No, Malloc, gMalloc, New, NewArray, File, Pipe, Many };
|
||||
enum AllocType { No, Malloc, gMalloc, New, NewArray, File, Pipe, Dir, Many };
|
||||
|
||||
// Extra allocation..
|
||||
class AllocFunc
|
||||
|
|
|
@ -217,6 +217,12 @@ private:
|
|||
TEST_CASE(strndup_function);
|
||||
TEST_CASE(fcloseall_function);
|
||||
TEST_CASE(file_functions);
|
||||
|
||||
TEST_CASE(opendir_function);
|
||||
TEST_CASE(fdopendir_function);
|
||||
TEST_CASE(closedir_function);
|
||||
TEST_CASE(dir_functions);
|
||||
|
||||
TEST_CASE(pointer_to_pointer);
|
||||
}
|
||||
|
||||
|
@ -2190,6 +2196,63 @@ private:
|
|||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
}
|
||||
|
||||
void opendir_function()
|
||||
{
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" DIR *f = opendir(\".\");\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Resource leak: f\n"), errout.str());
|
||||
}
|
||||
|
||||
void fdopendir_function()
|
||||
{
|
||||
check("void f(int fd)\n"
|
||||
"{\n"
|
||||
" DIR *f = fdopendir(fd);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:4]: (error) Resource leak: f\n"), errout.str());
|
||||
}
|
||||
|
||||
void closedir_function()
|
||||
{
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" DIR *f = opendir(\".\");\n"
|
||||
" closedir(f);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
|
||||
check("void f(int fd)\n"
|
||||
"{\n"
|
||||
" DIR *f = fdopendir(fd);\n"
|
||||
" closedir(f);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" DIR * f = opendir(dirname);\n"
|
||||
" if (closedir(f));\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string(""), errout.str());
|
||||
}
|
||||
|
||||
void dir_functions()
|
||||
{
|
||||
check("void f()\n"
|
||||
"{\n"
|
||||
" DIR *f = opendir(dir);\n"
|
||||
" readdir(f);\n;"
|
||||
" readdir_r(f, entry, res);\n;"
|
||||
" rewinddir(f);\n;"
|
||||
" telldir(f);\n;"
|
||||
" seekdir(f, 2)\n;"
|
||||
" scandir(f, namelist, filter, comp);\n;"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:10]: (error) Resource leak: f\n"), errout.str());
|
||||
}
|
||||
|
||||
void file_functions()
|
||||
{
|
||||
check("void f()\n"
|
||||
|
|
Loading…
Reference in New Issue