Environment: Refactoring and cleanup
This commit is contained in:
parent
2ba337faf7
commit
61e1dd5096
|
@ -486,8 +486,6 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
|||
// --std
|
||||
else if (std::strcmp(argv[i], "--std=posix") == 0) {
|
||||
_settings->standards.posix = true;
|
||||
} else if (std::strcmp(argv[i], "--std=gtk") == 0) {
|
||||
_settings->standards.gtk = true;
|
||||
} else if (std::strcmp(argv[i], "--std=c89") == 0) {
|
||||
_settings->standards.c = Standards::C89;
|
||||
} else if (std::strcmp(argv[i], "--std=c99") == 0) {
|
||||
|
@ -873,8 +871,6 @@ void CmdLineParser::PrintHelp()
|
|||
#endif
|
||||
" --std=<id> Set standard.\n"
|
||||
" The available options are:\n"
|
||||
" * gtk\n"
|
||||
" GTK code\n"
|
||||
" * posix\n"
|
||||
" POSIX compatible code\n"
|
||||
" * c89\n"
|
||||
|
|
|
@ -69,7 +69,7 @@ void VarInfo::possibleUsageAll(const std::string &functionName)
|
|||
|
||||
void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, int type)
|
||||
{
|
||||
const CheckMemoryLeak checkmemleak(_tokenizer, _errorLogger, _settings->standards);
|
||||
const CheckMemoryLeak checkmemleak(_tokenizer, _errorLogger, _settings);
|
||||
if (_settings->environment.isresource(type))
|
||||
checkmemleak.resourceLeakError(tok, varname);
|
||||
else
|
||||
|
@ -78,14 +78,14 @@ void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, i
|
|||
|
||||
void CheckLeakAutoVar::mismatchError(const Token *tok, const std::string &varname)
|
||||
{
|
||||
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings->standards);
|
||||
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings);
|
||||
std::list<const Token *> callstack(1, tok);
|
||||
c.mismatchAllocDealloc(callstack, varname);
|
||||
}
|
||||
|
||||
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname)
|
||||
{
|
||||
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings->standards);
|
||||
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings);
|
||||
c.deallocuseError(tok, varname);
|
||||
}
|
||||
|
||||
|
|
|
@ -148,27 +148,6 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
|
|||
if (varid && Token::Match(tok2, "realloc ( %any% ,") && tok2->tokAt(2)->varId() != varid)
|
||||
return Malloc;
|
||||
|
||||
// Does tok2 point on "g_malloc", "g_strdup", ..
|
||||
if (standards.gtk) {
|
||||
static const char * const gmallocfunc[] = {
|
||||
"g_new",
|
||||
"g_new0",
|
||||
"g_try_new",
|
||||
"g_try_new0",
|
||||
"g_malloc",
|
||||
"g_malloc0",
|
||||
"g_try_malloc",
|
||||
"g_try_malloc0",
|
||||
"g_strdup",
|
||||
"g_strndup",
|
||||
"g_strdup_printf"
|
||||
};
|
||||
for (unsigned int i = 0; i < sizeof(gmallocfunc)/sizeof(*gmallocfunc); i++) {
|
||||
if (tok2->str() == gmallocfunc[i])
|
||||
return gMalloc;
|
||||
}
|
||||
}
|
||||
|
||||
if (Token::Match(tok2, "new struct| %type% [;()]") ||
|
||||
Token::Match(tok2, "new ( std :: nothrow ) struct| %type% [;()]") ||
|
||||
Token::Match(tok2, "new ( nothrow ) struct| %type% [;()]"))
|
||||
|
@ -182,7 +161,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
|
|||
if (Token::Match(tok2, "fopen|tmpfile|g_fopen ("))
|
||||
return File;
|
||||
|
||||
if (standards.posix) {
|
||||
if (settings1->standards.posix) {
|
||||
if (Token::Match(tok2, "open|openat|creat|mkstemp|mkostemp (")) {
|
||||
// simple sanity check of function parameters..
|
||||
// TODO: Make such check for all these functions
|
||||
|
@ -202,6 +181,11 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getAllocationType(const Token *tok2,
|
|||
|
||||
if (Token::Match(tok2, "opendir|fdopendir ("))
|
||||
return Dir;
|
||||
|
||||
// Does tok2 point on "g_malloc", "g_strdup", ..
|
||||
const int alloctype = settings1->environment.alloc(tok2->str());
|
||||
if (alloctype > 0)
|
||||
return Environment::ismemory(alloctype) ? OtherMem : OtherRes;
|
||||
}
|
||||
|
||||
while (Token::Match(tok2,"%type%|%var% ::|. %type%"))
|
||||
|
@ -243,8 +227,7 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getReallocationType(const Token *tok
|
|||
return Malloc;
|
||||
|
||||
// GTK memory reallocation..
|
||||
if (Token::Match(tok2, "g_realloc|g_try_realloc|g_renew|g_try_renew"))
|
||||
return gMalloc;
|
||||
//if (Token::Match(tok2, "g_realloc|g_try_realloc|g_renew|g_try_renew"))
|
||||
|
||||
return No;
|
||||
}
|
||||
|
@ -272,17 +255,11 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok
|
|||
Token::Match(tok, "realloc ( %varid% , 0 ) ;", varid))
|
||||
return Malloc;
|
||||
|
||||
if (standards.gtk) {
|
||||
if (Token::Match(tok, "g_free ( %varid% ) ;", varid) ||
|
||||
Token::Match(tok, "g_free ( %varid% -", varid))
|
||||
return gMalloc;
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "fclose ( %varid% )", varid) ||
|
||||
Token::simpleMatch(tok, "fcloseall ( )"))
|
||||
return File;
|
||||
|
||||
if (standards.posix) {
|
||||
if (settings1->standards.posix) {
|
||||
if (Token::Match(tok, "close ( %varid% )", varid))
|
||||
return Fd;
|
||||
|
||||
|
@ -293,6 +270,13 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok
|
|||
return Dir;
|
||||
}
|
||||
|
||||
// Does tok2 point on "g_free", etc ..
|
||||
if (Token::Match(tok, "%type% ( %varid% )", varid)) {
|
||||
const int dealloctype = settings1->environment.dealloc(tok->str());
|
||||
if (dealloctype > 0)
|
||||
return Environment::ismemory(dealloctype) ? OtherMem : OtherRes;
|
||||
}
|
||||
|
||||
return No;
|
||||
}
|
||||
|
||||
|
@ -315,9 +299,6 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok
|
|||
Token::simpleMatch(tok, std::string("realloc ( " + varname + " , 0 ) ;").c_str()))
|
||||
return Malloc;
|
||||
|
||||
if (Token::simpleMatch(tok, std::string("g_free ( " + varname + " ) ;").c_str()))
|
||||
return gMalloc;
|
||||
|
||||
if (Token::simpleMatch(tok, std::string("fclose ( " + varname + " )").c_str()) ||
|
||||
Token::simpleMatch(tok, "fcloseall ( )"))
|
||||
return File;
|
||||
|
@ -331,6 +312,12 @@ CheckMemoryLeak::AllocType CheckMemoryLeak::getDeallocationType(const Token *tok
|
|||
if (Token::simpleMatch(tok, std::string("closedir ( " + varname + " )").c_str()))
|
||||
return Dir;
|
||||
|
||||
if (Token::Match(tok, ("%type% ( " + varname + " )").c_str())) {
|
||||
int type = settings1->environment.dealloc(tok->str());
|
||||
if (type > 0)
|
||||
return Environment::ismemory(type) ? OtherMem : OtherRes;
|
||||
}
|
||||
|
||||
return No;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ private:
|
|||
ErrorLogger * const errorLogger;
|
||||
|
||||
/** Enabled standards */
|
||||
const Standards & standards;
|
||||
const Settings * const settings1;
|
||||
|
||||
/** Disable the default constructors */
|
||||
CheckMemoryLeak();
|
||||
|
@ -88,12 +88,12 @@ private:
|
|||
void reportErr(const std::list<const Token *> &callstack, Severity::SeverityType severity, const std::string &id, const std::string &msg) const;
|
||||
|
||||
public:
|
||||
CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e, const Standards &s)
|
||||
: tokenizer(t), errorLogger(e), standards(s) {
|
||||
CheckMemoryLeak(const Tokenizer *t, ErrorLogger *e, const Settings *s)
|
||||
: tokenizer(t), errorLogger(e), settings1(s) {
|
||||
}
|
||||
|
||||
/** @brief 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, Fd, Pipe, Dir, Many };
|
||||
enum AllocType { No, Malloc, New, NewArray, File, Fd, Pipe, Dir, OtherMem, OtherRes, Many };
|
||||
|
||||
void memoryLeak(const Token *tok, const std::string &varname, AllocType alloctype);
|
||||
|
||||
|
@ -184,12 +184,12 @@ public:
|
|||
class CPPCHECKLIB CheckMemoryLeakInFunction : private Check, public CheckMemoryLeak {
|
||||
public:
|
||||
/** @brief This constructor is used when registering this class */
|
||||
CheckMemoryLeakInFunction() : Check(myName()), CheckMemoryLeak(0, 0, Standards()), symbolDatabase(NULL)
|
||||
CheckMemoryLeakInFunction() : Check(myName()), CheckMemoryLeak(0, 0, 0), symbolDatabase(NULL)
|
||||
{ }
|
||||
|
||||
/** @brief This constructor is used when running checks */
|
||||
CheckMemoryLeakInFunction(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings->standards) {
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings) {
|
||||
// get the symbol database
|
||||
if (tokenizr)
|
||||
symbolDatabase = tokenizr->getSymbolDatabase();
|
||||
|
@ -350,11 +350,11 @@ private:
|
|||
|
||||
class CPPCHECKLIB CheckMemoryLeakInClass : private Check, private CheckMemoryLeak {
|
||||
public:
|
||||
CheckMemoryLeakInClass() : Check(myName()), CheckMemoryLeak(0, 0, Standards())
|
||||
CheckMemoryLeakInClass() : Check(myName()), CheckMemoryLeak(0, 0, 0)
|
||||
{ }
|
||||
|
||||
CheckMemoryLeakInClass(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings->standards)
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings)
|
||||
{ }
|
||||
|
||||
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog) {
|
||||
|
@ -397,11 +397,11 @@ private:
|
|||
|
||||
class CPPCHECKLIB CheckMemoryLeakStructMember : private Check, private CheckMemoryLeak {
|
||||
public:
|
||||
CheckMemoryLeakStructMember() : Check(myName()), CheckMemoryLeak(0, 0, Standards())
|
||||
CheckMemoryLeakStructMember() : Check(myName()), CheckMemoryLeak(0, 0, 0)
|
||||
{ }
|
||||
|
||||
CheckMemoryLeakStructMember(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings->standards)
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings)
|
||||
{ }
|
||||
|
||||
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog) {
|
||||
|
@ -436,11 +436,11 @@ private:
|
|||
|
||||
class CPPCHECKLIB CheckMemoryLeakNoVar : private Check, private CheckMemoryLeak {
|
||||
public:
|
||||
CheckMemoryLeakNoVar() : Check(myName()), CheckMemoryLeak(0, 0, Standards())
|
||||
CheckMemoryLeakNoVar() : Check(myName()), CheckMemoryLeak(0, 0, 0)
|
||||
{ }
|
||||
|
||||
CheckMemoryLeakNoVar(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog)
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings->standards)
|
||||
: Check(myName(), tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog, settings)
|
||||
{ }
|
||||
|
||||
void runSimplifiedChecks(const Tokenizer *tokenizr, const Settings *settings, ErrorLogger *errLog) {
|
||||
|
|
|
@ -49,28 +49,27 @@ bool Environment::load(const char path[])
|
|||
return false;
|
||||
|
||||
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
|
||||
if (strcmp(rootnode->Value(),"def") != 0)
|
||||
if (strcmp(rootnode->Name(),"def") != 0)
|
||||
return false;
|
||||
|
||||
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
|
||||
if (strcmp(node->Value(),"memory")==0) {
|
||||
if (strcmp(node->Name(),"memory")==0) {
|
||||
while (!ismemory(++allocid));
|
||||
for (const tinyxml2::XMLElement *memorynode = node->FirstChildElement(); memorynode; memorynode = memorynode->NextSiblingElement()) {
|
||||
if (strcmp(memorynode->Value(),"alloc")==0)
|
||||
_alloc[node->GetText()] = allocid;
|
||||
else if (strcmp(memorynode->Value(),"dealloc")==0)
|
||||
_dealloc[node->GetText()] = allocid;
|
||||
else if (strcmp(node->Value(),"use")==0)
|
||||
use.insert(node->GetText());
|
||||
if (strcmp(memorynode->Name(),"alloc")==0)
|
||||
_alloc[memorynode->GetText()] = allocid;
|
||||
else if (strcmp(memorynode->Name(),"dealloc")==0)
|
||||
_dealloc[memorynode->GetText()] = allocid;
|
||||
else if (strcmp(memorynode->Name(),"use")==0)
|
||||
use.insert(memorynode->GetText());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (strcmp(node->Value(),"ignore")==0)
|
||||
else if (strcmp(node->Name(),"ignore")==0)
|
||||
ignore.insert(node->GetText());
|
||||
else if (strcmp(node->Value(),"noreturn")==0)
|
||||
else if (strcmp(node->Name(),"noreturn")==0)
|
||||
noreturn.insert(node->GetText());
|
||||
else
|
||||
return false;
|
||||
|
|
|
@ -33,14 +33,11 @@ struct Standards {
|
|||
/** C++ code standard */
|
||||
enum cppstd_t { CPP03, CPP11 } cpp;
|
||||
|
||||
/** Code is gtk */
|
||||
bool gtk;
|
||||
|
||||
/** Code is posix */
|
||||
bool posix;
|
||||
|
||||
/** This constructor clear all the variables **/
|
||||
Standards() : c(C11), cpp(CPP11), gtk(false), posix(false) {}
|
||||
Standards() : c(C11), cpp(CPP11), posix(false) {}
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
|
|
@ -44,14 +44,13 @@ private:
|
|||
errout.str("");
|
||||
|
||||
Settings settings;
|
||||
settings.standards.gtk = true;
|
||||
|
||||
// Tokenize..
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
|
||||
CheckMemoryLeak c(&tokenizer, this, settings.standards);
|
||||
CheckMemoryLeak c(&tokenizer, this, &settings);
|
||||
|
||||
return c.functionReturnType(&tokenizer.getSymbolDatabase()->scopeList.front().functionList.front());
|
||||
}
|
||||
|
@ -108,7 +107,7 @@ private:
|
|||
|
||||
// there is no allocation
|
||||
const Token *tok = Token::findsimplematch(tokenizer.tokens(), "ret =");
|
||||
CheckMemoryLeak check(&tokenizer, 0, settings.standards);
|
||||
CheckMemoryLeak check(&tokenizer, 0, &settings);
|
||||
ASSERT_EQUALS(CheckMemoryLeak::No, check.getAllocationType(tok->tokAt(2), 1));
|
||||
}
|
||||
};
|
||||
|
@ -371,7 +370,6 @@ private:
|
|||
errout.str("");
|
||||
|
||||
Settings settings;
|
||||
settings.standards.gtk = true;
|
||||
settings.standards.posix = true;
|
||||
|
||||
// Tokenize..
|
||||
|
@ -412,7 +410,6 @@ private:
|
|||
ASSERT_EQUALS(";;alloc;", getcode("int *a = new int[10];", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int * const a = new int[10];", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("const int * const a = new int[10];", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("char *a = g_strdup_printf(\"%i\", f());", "a"));
|
||||
ASSERT_EQUALS(";;alloc;", getcode("int i = open(a,b);", "i"));
|
||||
ASSERT_EQUALS(";;assign;", getcode("int i = open();", "i"));
|
||||
|
||||
|
|
Loading…
Reference in New Issue