Environment: Refactoring and cleanup

This commit is contained in:
Daniel Marjamäki 2013-07-05 20:55:31 +02:00
parent 2ba337faf7
commit 61e1dd5096
7 changed files with 49 additions and 73 deletions

View File

@ -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"

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;

View File

@ -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) {}
};
/// @}

View File

@ -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"));