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 ("))
|
if (Token::simpleMatch(tok2, "popen ("))
|
||||||
return Pipe;
|
return Pipe;
|
||||||
|
|
||||||
|
if (Token::Match(tok2, "opendir|fdopendir ("))
|
||||||
|
return Dir;
|
||||||
|
|
||||||
// Userdefined allocation function..
|
// Userdefined allocation function..
|
||||||
std::list<AllocFunc>::const_iterator it = _listAllocFunc.begin();
|
std::list<AllocFunc>::const_iterator it = _listAllocFunc.begin();
|
||||||
while (it != _listAllocFunc.end())
|
while (it != _listAllocFunc.end())
|
||||||
|
@ -181,9 +184,7 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType(const
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, std::string("free ( " + names + " ) ;").c_str()) ||
|
if (Token::simpleMatch(tok, std::string("free ( " + names + " ) ;").c_str()) ||
|
||||||
Token::simpleMatch(tok, std::string("kfree ( " + names + " ) ;").c_str()))
|
Token::simpleMatch(tok, std::string("kfree ( " + names + " ) ;").c_str()))
|
||||||
{
|
|
||||||
return Malloc;
|
return Malloc;
|
||||||
}
|
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, std::string("g_free ( " + names + " ) ;").c_str()))
|
if (Token::simpleMatch(tok, std::string("g_free ( " + names + " ) ;").c_str()))
|
||||||
return gMalloc;
|
return gMalloc;
|
||||||
|
@ -195,6 +196,9 @@ CheckMemoryLeakClass::AllocType CheckMemoryLeakClass::GetDeallocationType(const
|
||||||
if (Token::simpleMatch(tok, std::string("pclose ( " + names + " )").c_str()))
|
if (Token::simpleMatch(tok, std::string("pclose ( " + names + " )").c_str()))
|
||||||
return Pipe;
|
return Pipe;
|
||||||
|
|
||||||
|
if (Token::simpleMatch(tok, std::string("closedir ( " + names + " )").c_str()))
|
||||||
|
return Dir;
|
||||||
|
|
||||||
return No;
|
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"))
|
Token::Match(tok, "setvbuf|setbuf|setbuffer|setlinebuf|rewind"))
|
||||||
return 0;
|
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..
|
// Convert functions that are not allocating nor deallocating memory..
|
||||||
if (Token::Match(tok, "atoi|atof|atol|strtol|strtoul|strtod"))
|
if (Token::Match(tok, "atoi|atof|atol|strtol|strtoul|strtod"))
|
||||||
return 0;
|
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)
|
void CheckMemoryLeakClass::MemoryLeak(const Token *tok, const char varname[], AllocType alloctype, bool all)
|
||||||
{
|
{
|
||||||
if (alloctype == CheckMemoryLeakClass::File ||
|
if (alloctype == CheckMemoryLeakClass::File ||
|
||||||
alloctype == CheckMemoryLeakClass::Pipe)
|
alloctype == CheckMemoryLeakClass::Pipe ||
|
||||||
|
alloctype == CheckMemoryLeakClass::Dir)
|
||||||
resourceLeakError(tok, varname);
|
resourceLeakError(tok, varname);
|
||||||
else if (all)
|
else if (all)
|
||||||
memleakallError(tok, varname);
|
memleakallError(tok, varname);
|
||||||
|
@ -544,7 +554,7 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list<const Token *>
|
||||||
if (parlevel <= 0)
|
if (parlevel <= 0)
|
||||||
break;
|
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("dealloc");
|
||||||
addtoken(";");
|
addtoken(";");
|
||||||
|
|
|
@ -56,7 +56,7 @@ public:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/** What type of allocation are used.. the "Many" means that several types of allocation and deallocation are used */
|
/** 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..
|
// Extra allocation..
|
||||||
class AllocFunc
|
class AllocFunc
|
||||||
|
|
|
@ -82,7 +82,7 @@ void CheckOther::WarningRedundantCode()
|
||||||
varname1 = tok->strAt(2);
|
varname1 = tok->strAt(2);
|
||||||
tok2 = tok->tokAt(4);
|
tok2 = tok->tokAt(4);
|
||||||
}
|
}
|
||||||
else if (Token::Match(tok, "if ( %var% != NULL )"))
|
else if (Token::Match(tok, "if ( %var% != 0 )"))
|
||||||
{
|
{
|
||||||
varname1 = tok->strAt(2);
|
varname1 = tok->strAt(2);
|
||||||
tok2 = tok->tokAt(6);
|
tok2 = tok->tokAt(6);
|
||||||
|
@ -102,7 +102,7 @@ void CheckOther::WarningRedundantCode()
|
||||||
}
|
}
|
||||||
else if (Token::Match(tok2, "delete [ ] %var% ; }"))
|
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% ) ; }"))
|
else if (Token::Match(tok2, "free ( %var% ) ; }"))
|
||||||
{
|
{
|
||||||
|
@ -121,7 +121,7 @@ void CheckOther::WarningRedundantCode()
|
||||||
}
|
}
|
||||||
else if (Token::Match(tok2, "delete [ ] %var% ;"))
|
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% ) ;"))
|
else if (Token::Match(tok2, "free ( %var% ) ;"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -217,6 +217,12 @@ private:
|
||||||
TEST_CASE(strndup_function);
|
TEST_CASE(strndup_function);
|
||||||
TEST_CASE(fcloseall_function);
|
TEST_CASE(fcloseall_function);
|
||||||
TEST_CASE(file_functions);
|
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);
|
TEST_CASE(pointer_to_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2190,6 +2196,63 @@ private:
|
||||||
ASSERT_EQUALS(std::string(""), errout.str());
|
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()
|
void file_functions()
|
||||||
{
|
{
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
|
|
|
@ -145,6 +145,20 @@ private:
|
||||||
" delete p;\n"
|
" delete p;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS(std::string("[test.cpp:3]: (style) Redundant condition. It is safe to deallocate a NULL pointer\n"), errout.str());
|
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()
|
void unreachable1()
|
||||||
|
|
Loading…
Reference in New Issue