Merge commit 'd0k/master'
This commit is contained in:
commit
99938353b4
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -37,6 +38,28 @@ CheckMemoryLeakInClass instance2;
|
||||||
CheckMemoryLeakStructMember instance3;
|
CheckMemoryLeakStructMember instance3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This list needs to be alphabetically sorted so we can run bsearch on it
|
||||||
|
static const char * const call_func_white_list[] =
|
||||||
|
{
|
||||||
|
"atof", "atoi", "atol", "clearerr", "delete", "fchmod", "fcntl"
|
||||||
|
, "fdatasync", "feof", "ferror", "fflush", "fgetc", "fgetpos", "fgets"
|
||||||
|
, "flock", "for", "fprintf", "fputc", "fputs", "fread", "fseek"
|
||||||
|
, "fseeko", "fsetpos", "fstat", "fsync", "ftell", "ftello", "ftruncate"
|
||||||
|
, "fwrite", "getc", "if", "ioctl", "lockf", "lseek", "memchr", "memcpy"
|
||||||
|
, "memmove", "memset", "posix_fadvise", "posix_fallocate", "pread"
|
||||||
|
, "printf", "pwrite", "read", "readahead", "readdir", "readdir_r", "readv"
|
||||||
|
, "realloc", "return", "rewind", "rewinddir", "scandir", "seekdir"
|
||||||
|
, "setbuf", "setbuffer", "setlinebuf", "setvbuf", "sprintf", "strcasecmp"
|
||||||
|
, "strcat", "strchr", "strcmp", "strcpy", "stricmp", "strncat", "strncmp"
|
||||||
|
, "strncpy", "strrchr", "strstr", "strtod", "strtol", "strtoul", "switch"
|
||||||
|
, "sync_file_range", "telldir", "while", "write", "writev"
|
||||||
|
};
|
||||||
|
|
||||||
|
static int call_func_white_list_compare(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
return strcmp((const char *)a, *(const char **)b);
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CheckMemoryLeak::isclass(const Tokenizer *_tokenizer, const Token *tok) const
|
bool CheckMemoryLeak::isclass(const Tokenizer *_tokenizer, const Token *tok) const
|
||||||
|
@ -407,35 +430,6 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::functionReturnType(const Token *tok)
|
||||||
return No;
|
return No;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckMemoryLeakInFunction::init()
|
|
||||||
{
|
|
||||||
static const char * const white_list[] =
|
|
||||||
{
|
|
||||||
"if", "for", "while", "return", "switch", "realloc", "delete"
|
|
||||||
, "strcpy", "strncpy", "strcat", "strncat", "strcmp", "strncmp"
|
|
||||||
, "strcasecmp", "stricmp", "sprintf", "strchr", "strrchr", "strstr"
|
|
||||||
, "memset", "memcpy", "memmove", "memchr", "fgets", "fgetc", "getc"
|
|
||||||
, "fputs", "fputc", "feof", "ferror", "clearerr", "printf", "fprintf"
|
|
||||||
, "fread", "fwrite", "fflush", "fseek", "fseeko", "ftell", "ftello"
|
|
||||||
, "fsetpos", "fgetpos", "setvbuf", "setbuf", "setbuffer", "setlinebuf"
|
|
||||||
, "rewind", "read", "readv", "pread", "readahead", "write", "writev"
|
|
||||||
, "pwrite", "lseek", "ioctl", "fchmod", "fcntl", "flock", "lockf"
|
|
||||||
, "ftruncate", "fsync", "fdatasync", "fstat", "sync_file_range"
|
|
||||||
, "posix_fallocate", "posix_fadvise", "readdir", "readdir_r"
|
|
||||||
, "rewinddir", "telldir", "seekdir", "scandir", "atoi", "atof", "atol"
|
|
||||||
, "strtol", "strtoul", "strtod"
|
|
||||||
, NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
while (white_list[i] != NULL)
|
|
||||||
{
|
|
||||||
call_func_white_list.insert(white_list[i]);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckMemoryLeakInFunction::matchFunctionsThatReturnArg(const Token *tok, const unsigned int varid) const
|
bool CheckMemoryLeakInFunction::matchFunctionsThatReturnArg(const Token *tok, const unsigned int varid) const
|
||||||
{
|
{
|
||||||
return Token::Match(tok, "; %varid% = strcat|memcpy|memmove|strcpy ( %varid% ,", varid);
|
return Token::Match(tok, "; %varid% = strcat|memcpy|memmove|strcpy ( %varid% ,", varid);
|
||||||
|
@ -480,7 +474,9 @@ static int countParameters(const Token *tok)
|
||||||
|
|
||||||
const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, AllocType &alloctype, AllocType &dealloctype, bool &all, unsigned int sz)
|
const char * CheckMemoryLeakInFunction::call_func(const Token *tok, std::list<const Token *> callstack, const unsigned int varid, AllocType &alloctype, AllocType &dealloctype, bool &all, unsigned int sz)
|
||||||
{
|
{
|
||||||
if (call_func_white_list.find(tok->str()) != call_func_white_list.end())
|
if (bsearch(tok->str().c_str(), call_func_white_list,
|
||||||
|
sizeof(call_func_white_list) / sizeof(call_func_white_list[0]),
|
||||||
|
sizeof(call_func_white_list[0]), call_func_white_list_compare))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No)
|
if (getAllocationType(tok, varid) != No || getReallocationType(tok, varid) != No || getDeallocationType(tok, varid) != No)
|
||||||
|
|
|
@ -145,16 +145,12 @@ class CheckMemoryLeakInFunction : private Check, private CheckMemoryLeak
|
||||||
public:
|
public:
|
||||||
/** This constructor is used when registering this class */
|
/** This constructor is used when registering this class */
|
||||||
CheckMemoryLeakInFunction() : Check(), CheckMemoryLeak(0, 0)
|
CheckMemoryLeakInFunction() : Check(), CheckMemoryLeak(0, 0)
|
||||||
{
|
{ }
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** This constructor is used when running checks */
|
/** This constructor is used when running checks */
|
||||||
CheckMemoryLeakInFunction(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
CheckMemoryLeakInFunction(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
: Check(tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger)
|
: Check(tokenizer, settings, errorLogger), CheckMemoryLeak(tokenizer, errorLogger)
|
||||||
{
|
{ }
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
|
||||||
{
|
{
|
||||||
|
@ -272,13 +268,6 @@ private:
|
||||||
{
|
{
|
||||||
return "Is there any allocated memory when a function goes out of scope";
|
return "Is there any allocated memory when a function goes out of scope";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keywords and function names which not allocating nor deallocating memory
|
|
||||||
// (used by call_func())
|
|
||||||
std::set<std::string> call_func_white_list;
|
|
||||||
|
|
||||||
// Called in all constructors
|
|
||||||
void init();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -488,21 +488,6 @@ bool Token::Match(const Token *tok, const char pattern[], unsigned int varid)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Token::isName() const
|
|
||||||
{
|
|
||||||
return _isName;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Token::isNumber() const
|
|
||||||
{
|
|
||||||
return _isNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Token::isBoolean() const
|
|
||||||
{
|
|
||||||
return _isBoolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Token::isStandardType() const
|
bool Token::isStandardType() const
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
@ -524,36 +509,6 @@ const Token *Token::findmatch(const Token *tok, const char pattern[], unsigned i
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Token::varId() const
|
|
||||||
{
|
|
||||||
return _varId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::varId(unsigned int id)
|
|
||||||
{
|
|
||||||
_varId = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token *Token::next() const
|
|
||||||
{
|
|
||||||
return _next;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::next(Token *next)
|
|
||||||
{
|
|
||||||
_next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token *Token::previous() const
|
|
||||||
{
|
|
||||||
return _previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::previous(Token *previous)
|
|
||||||
{
|
|
||||||
_previous = previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::insertToken(const char str[])
|
void Token::insertToken(const char str[])
|
||||||
{
|
{
|
||||||
Token *newToken = new Token;
|
Token *newToken = new Token;
|
||||||
|
@ -581,36 +536,6 @@ void Token::eraseTokens(Token *begin, const Token *end)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Token::fileIndex() const
|
|
||||||
{
|
|
||||||
return _fileIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::fileIndex(unsigned int fileIndex)
|
|
||||||
{
|
|
||||||
_fileIndex = fileIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Token::linenr() const
|
|
||||||
{
|
|
||||||
return _linenr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::linenr(unsigned int linenr)
|
|
||||||
{
|
|
||||||
_linenr = linenr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::link(Token *link)
|
|
||||||
{
|
|
||||||
_link = link;
|
|
||||||
}
|
|
||||||
|
|
||||||
Token *Token::link() const
|
|
||||||
{
|
|
||||||
return _link;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Token::createMutualLinks(Token *begin, Token *end)
|
void Token::createMutualLinks(Token *begin, Token *end)
|
||||||
{
|
{
|
||||||
assert(begin != NULL);
|
assert(begin != NULL);
|
||||||
|
|
30
src/token.h
30
src/token.h
|
@ -117,9 +117,9 @@ public:
|
||||||
*/
|
*/
|
||||||
static bool Match(const Token *tok, const char pattern[], unsigned int varid = 0);
|
static bool Match(const Token *tok, const char pattern[], unsigned int varid = 0);
|
||||||
|
|
||||||
bool isName() const;
|
bool isName() const { return _isName; }
|
||||||
bool isNumber() const;
|
bool isNumber() const { return _isNumber; }
|
||||||
bool isBoolean() const;
|
bool isBoolean() const { return _isBoolean; }
|
||||||
bool isStandardType() const;
|
bool isStandardType() const;
|
||||||
|
|
||||||
static const Token *findmatch(const Token *tok, const char pattern[], unsigned int varId = 0);
|
static const Token *findmatch(const Token *tok, const char pattern[], unsigned int varId = 0);
|
||||||
|
@ -139,13 +139,13 @@ public:
|
||||||
*/
|
*/
|
||||||
static int multiCompare(const char *haystack, const char *needle);
|
static int multiCompare(const char *haystack, const char *needle);
|
||||||
|
|
||||||
unsigned int linenr() const;
|
unsigned int linenr() const { return _linenr; }
|
||||||
void linenr(unsigned int linenr);
|
void linenr(unsigned int linenr) { _linenr = linenr; }
|
||||||
|
|
||||||
unsigned int fileIndex() const;
|
unsigned int fileIndex() const { return _fileIndex; }
|
||||||
void fileIndex(unsigned int fileIndex);
|
void fileIndex(unsigned int fileIndex) { _fileIndex = fileIndex; }
|
||||||
|
|
||||||
Token *next() const;
|
Token *next() const { return _next; }
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,11 +164,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void insertToken(const char str[]);
|
void insertToken(const char str[]);
|
||||||
|
|
||||||
Token *previous() const;
|
Token *previous() const { return _previous; }
|
||||||
|
|
||||||
|
|
||||||
unsigned int varId() const;
|
unsigned int varId() const { return _varId; }
|
||||||
void varId(unsigned int id);
|
void varId(unsigned int id) { _varId = id; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For debugging purposes, prints token and all tokens
|
* For debugging purposes, prints token and all tokens
|
||||||
|
@ -202,7 +202,7 @@ public:
|
||||||
* @param link The token where this token should link
|
* @param link The token where this token should link
|
||||||
* to.
|
* to.
|
||||||
*/
|
*/
|
||||||
void link(Token *link);
|
void link(Token *link) { _link = link; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return token where this token links to.
|
* Return token where this token links to.
|
||||||
|
@ -211,7 +211,7 @@ public:
|
||||||
*
|
*
|
||||||
* @return The token where this token links to.
|
* @return The token where this token links to.
|
||||||
*/
|
*/
|
||||||
Token *link() const;
|
Token *link() const { return _link; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Links two elements against each other.
|
* Links two elements against each other.
|
||||||
|
@ -219,8 +219,8 @@ public:
|
||||||
static void createMutualLinks(Token *begin, Token *end);
|
static void createMutualLinks(Token *begin, Token *end);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void next(Token *next);
|
void next(Token *next) { _next = next; }
|
||||||
void previous(Token *previous);
|
void previous(Token *previous) { _previous = previous; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Works almost like strcmp() except returns only 0 or 1 and
|
* Works almost like strcmp() except returns only 0 or 1 and
|
||||||
|
|
Loading…
Reference in New Issue