Merge branch 'master' of git@github.com:danmar/cppcheck
This commit is contained in:
commit
d53eb9e303
|
@ -116,6 +116,9 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetAllocationType(const To
|
|||
if (Token::simpleMatch(tok2, "popen ("))
|
||||
return Pipe;
|
||||
|
||||
if (Token::Match(tok2, "opendir|fdopendir ("))
|
||||
return Dir;
|
||||
|
||||
// Userdefined allocation function..
|
||||
std::list<AllocFunc>::const_iterator it = _listAllocFunc.begin();
|
||||
while (it != _listAllocFunc.end())
|
||||
|
@ -181,9 +184,7 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType(const
|
|||
|
||||
if (Token::simpleMatch(tok, std::string("free ( " + names + " ) ;").c_str()) ||
|
||||
Token::simpleMatch(tok, std::string("kfree ( " + names + " ) ;").c_str()))
|
||||
{
|
||||
return Malloc;
|
||||
}
|
||||
|
||||
if (Token::simpleMatch(tok, std::string("g_free ( " + names + " ) ;").c_str()))
|
||||
return gMalloc;
|
||||
|
@ -195,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;
|
||||
}
|
||||
//--------------------------------------------------------------------------
|
||||
|
@ -219,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;
|
||||
|
@ -308,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);
|
||||
|
@ -544,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
|
||||
|
|
|
@ -82,7 +82,7 @@ void CheckOther::WarningRedundantCode()
|
|||
varname1 = tok->strAt(2);
|
||||
tok2 = tok->tokAt(4);
|
||||
}
|
||||
else if (Token::Match(tok, "if ( %var% != NULL )"))
|
||||
else if (Token::Match(tok, "if ( %var% != 0 )"))
|
||||
{
|
||||
varname1 = tok->strAt(2);
|
||||
tok2 = tok->tokAt(6);
|
||||
|
@ -102,7 +102,7 @@ void CheckOther::WarningRedundantCode()
|
|||
}
|
||||
else if (Token::Match(tok2, "delete [ ] %var% ; }"))
|
||||
{
|
||||
err = (strcmp(tok2->strAt(1), varname1) == 0);
|
||||
err = (strcmp(tok2->strAt(3), varname1) == 0);
|
||||
}
|
||||
else if (Token::Match(tok2, "free ( %var% ) ; }"))
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ void CheckOther::WarningRedundantCode()
|
|||
}
|
||||
else if (Token::Match(tok2, "delete [ ] %var% ;"))
|
||||
{
|
||||
err = (strcmp(tok2->strAt(1), varname1) == 0);
|
||||
err = (strcmp(tok2->strAt(3), varname1) == 0);
|
||||
}
|
||||
else if (Token::Match(tok2, "free ( %var% ) ;"))
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -145,6 +145,20 @@ private:
|
|||
" delete p;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" if (p != NULL)\n"
|
||||
" delete p;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str());
|
||||
|
||||
check("void foo()\n"
|
||||
"{\n"
|
||||
" if (p)\n"
|
||||
" delete [] p;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str());
|
||||
}
|
||||
|
||||
void unreachable1()
|
||||
|
|
Loading…
Reference in New Issue