CLI: Added --environment flag
This commit is contained in:
parent
1a35241aa2
commit
d96fb577cd
8
Makefile
8
Makefile
|
@ -75,7 +75,7 @@ ifndef PREFIX
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef INCLUDE_FOR_LIB
|
ifndef INCLUDE_FOR_LIB
|
||||||
INCLUDE_FOR_LIB=-Ilib
|
INCLUDE_FOR_LIB=-Ilib -Iexternals -Iexternals/tinyxml
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef INCLUDE_FOR_CLI
|
ifndef INCLUDE_FOR_CLI
|
||||||
|
@ -120,6 +120,7 @@ LIBOBJ = $(SRCDIR)/check64bit.o \
|
||||||
$(SRCDIR)/checkunusedfunctions.o \
|
$(SRCDIR)/checkunusedfunctions.o \
|
||||||
$(SRCDIR)/checkunusedvar.o \
|
$(SRCDIR)/checkunusedvar.o \
|
||||||
$(SRCDIR)/cppcheck.o \
|
$(SRCDIR)/cppcheck.o \
|
||||||
|
$(SRCDIR)/environment.o \
|
||||||
$(SRCDIR)/errorlogger.o \
|
$(SRCDIR)/errorlogger.o \
|
||||||
$(SRCDIR)/executionpath.o \
|
$(SRCDIR)/executionpath.o \
|
||||||
$(SRCDIR)/mathlib.o \
|
$(SRCDIR)/mathlib.o \
|
||||||
|
@ -285,7 +286,7 @@ $(SRCDIR)/checknullpointer.o: lib/checknullpointer.cpp lib/checknullpointer.h li
|
||||||
$(SRCDIR)/checkobsoletefunctions.o: lib/checkobsoletefunctions.cpp lib/checkobsoletefunctions.h lib/config.h lib/check.h lib/token.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/standards.h lib/symboldatabase.h lib/mathlib.h
|
$(SRCDIR)/checkobsoletefunctions.o: lib/checkobsoletefunctions.cpp lib/checkobsoletefunctions.h lib/config.h lib/check.h lib/token.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/standards.h lib/symboldatabase.h lib/mathlib.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/checkobsoletefunctions.o $(SRCDIR)/checkobsoletefunctions.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/checkobsoletefunctions.o $(SRCDIR)/checkobsoletefunctions.cpp
|
||||||
|
|
||||||
$(SRCDIR)/checkother.o: lib/checkother.cpp lib/checkother.h lib/config.h lib/check.h lib/token.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/standards.h lib/mathlib.h lib/symboldatabase.h
|
$(SRCDIR)/checkother.o: lib/checkother.cpp lib/checkother.h lib/config.h lib/check.h lib/token.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/standards.h lib/mathlib.h lib/symboldatabase.h lib/templatesimplifier.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/checkother.o $(SRCDIR)/checkother.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/checkother.o $(SRCDIR)/checkother.cpp
|
||||||
|
|
||||||
$(SRCDIR)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/checkpostfixoperator.h lib/config.h lib/check.h lib/token.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/standards.h lib/symboldatabase.h lib/mathlib.h
|
$(SRCDIR)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/checkpostfixoperator.h lib/config.h lib/check.h lib/token.h lib/tokenize.h lib/errorlogger.h lib/suppressions.h lib/tokenlist.h lib/settings.h lib/standards.h lib/symboldatabase.h lib/mathlib.h
|
||||||
|
@ -309,6 +310,9 @@ $(SRCDIR)/checkunusedvar.o: lib/checkunusedvar.cpp lib/checkunusedvar.h lib/conf
|
||||||
$(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cppcheck.h lib/config.h lib/settings.h lib/suppressions.h lib/standards.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/preprocessor.h lib/path.h lib/timer.h
|
$(SRCDIR)/cppcheck.o: lib/cppcheck.cpp lib/cppcheck.h lib/config.h lib/settings.h lib/suppressions.h lib/standards.h lib/errorlogger.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/preprocessor.h lib/path.h lib/timer.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/cppcheck.o $(SRCDIR)/cppcheck.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/cppcheck.o $(SRCDIR)/cppcheck.cpp
|
||||||
|
|
||||||
|
$(SRCDIR)/environment.o: lib/environment.cpp lib/environment.h
|
||||||
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/environment.o $(SRCDIR)/environment.cpp
|
||||||
|
|
||||||
$(SRCDIR)/errorlogger.o: lib/errorlogger.cpp lib/errorlogger.h lib/config.h lib/suppressions.h lib/path.h lib/cppcheck.h lib/settings.h lib/standards.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/tokenlist.h
|
$(SRCDIR)/errorlogger.o: lib/errorlogger.cpp lib/errorlogger.h lib/config.h lib/suppressions.h lib/path.h lib/cppcheck.h lib/settings.h lib/standards.h lib/checkunusedfunctions.h lib/check.h lib/token.h lib/tokenize.h lib/tokenlist.h
|
||||||
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/errorlogger.o $(SRCDIR)/errorlogger.cpp
|
$(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $(SRCDIR)/errorlogger.o $(SRCDIR)/errorlogger.cpp
|
||||||
|
|
||||||
|
|
|
@ -328,6 +328,14 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --environment
|
||||||
|
else if (std::strncmp(argv[i], "--environment=", 14) == 0) {
|
||||||
|
if (!_settings->environment.load(argv[i]+14)) {
|
||||||
|
PrintMessage("cppcheck: Failed to load environment file '" + std::string(argv[i]+14) + "'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// --error-exitcode=1
|
// --error-exitcode=1
|
||||||
else if (std::strncmp(argv[i], "--error-exitcode=", 17) == 0) {
|
else if (std::strncmp(argv[i], "--error-exitcode=", 17) == 0) {
|
||||||
std::string temp = argv[i]+17;
|
std::string temp = argv[i]+17;
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const int DEALLOC = -1;
|
||||||
|
const int NOALLOC = 0;
|
||||||
|
|
||||||
// Register this check class (by creating a static instance of it)
|
// Register this check class (by creating a static instance of it)
|
||||||
namespace {
|
namespace {
|
||||||
CheckLeakAutoVar instance;
|
CheckLeakAutoVar instance;
|
||||||
|
@ -43,7 +46,7 @@ namespace {
|
||||||
void VarInfo::print()
|
void VarInfo::print()
|
||||||
{
|
{
|
||||||
std::cout << "size=" << alloctype.size() << std::endl;
|
std::cout << "size=" << alloctype.size() << std::endl;
|
||||||
std::map<unsigned int, std::string>::const_iterator it;
|
std::map<unsigned int, int>::const_iterator it;
|
||||||
for (it = alloctype.begin(); it != alloctype.end(); ++it) {
|
for (it = alloctype.begin(); it != alloctype.end(); ++it) {
|
||||||
std::string strusage;
|
std::string strusage;
|
||||||
std::map<unsigned int, std::string>::const_iterator use = possibleUsage.find(it->first);
|
std::map<unsigned int, std::string>::const_iterator use = possibleUsage.find(it->first);
|
||||||
|
@ -58,20 +61,19 @@ void VarInfo::print()
|
||||||
void VarInfo::possibleUsageAll(const std::string &functionName)
|
void VarInfo::possibleUsageAll(const std::string &functionName)
|
||||||
{
|
{
|
||||||
possibleUsage.clear();
|
possibleUsage.clear();
|
||||||
std::map<unsigned int, std::string>::const_iterator it;
|
std::map<unsigned int, int>::const_iterator it;
|
||||||
for (it = alloctype.begin(); it != alloctype.end(); ++it)
|
for (it = alloctype.begin(); it != alloctype.end(); ++it)
|
||||||
possibleUsage[it->first] = functionName;
|
possibleUsage[it->first] = functionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CheckLeakAutoVar::leakError(const Token *tok, const std::string &varname, const std::string &type)
|
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->standards);
|
||||||
if (type == "fopen")
|
if (_settings->environment.isresource(type))
|
||||||
checkmemleak.resourceLeakError(tok, varname);
|
checkmemleak.resourceLeakError(tok, varname);
|
||||||
else
|
else
|
||||||
checkmemleak.memleakError(tok, varname);
|
checkmemleak.memleakError(tok, varname);
|
||||||
//reportError(tok, Severity::error, "newleak", "New memory leak: " + varname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::mismatchError(const Token *tok, const std::string &varname)
|
void CheckLeakAutoVar::mismatchError(const Token *tok, const std::string &varname)
|
||||||
|
@ -79,14 +81,12 @@ void CheckLeakAutoVar::mismatchError(const Token *tok, const std::string &varnam
|
||||||
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings->standards);
|
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings->standards);
|
||||||
std::list<const Token *> callstack(1, tok);
|
std::list<const Token *> callstack(1, tok);
|
||||||
c.mismatchAllocDealloc(callstack, varname);
|
c.mismatchAllocDealloc(callstack, varname);
|
||||||
//reportError(tok, Severity::error, "newmismatch", "New mismatching allocation and deallocation: " + varname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname)
|
void CheckLeakAutoVar::deallocUseError(const Token *tok, const std::string &varname)
|
||||||
{
|
{
|
||||||
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings->standards);
|
const CheckMemoryLeak c(_tokenizer, _errorLogger, _settings->standards);
|
||||||
c.deallocuseError(tok, varname);
|
c.deallocuseError(tok, varname);
|
||||||
//reportError(tok, Severity::error, "newdeallocuse", "Using deallocated pointer " + varname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::deallocReturnError(const Token *tok, const std::string &varname)
|
void CheckLeakAutoVar::deallocReturnError(const Token *tok, const std::string &varname)
|
||||||
|
@ -96,7 +96,7 @@ void CheckLeakAutoVar::deallocReturnError(const Token *tok, const std::string &v
|
||||||
|
|
||||||
void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::string &functionName)
|
void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::string &functionName)
|
||||||
{
|
{
|
||||||
if (((!cfgalloc.empty() || !cfgdealloc.empty()) && _settings->isEnabled("information")) || _settings->experimental) {
|
if (_settings->isEnabled("information") && _settings->experimental) {
|
||||||
reportError(tok,
|
reportError(tok,
|
||||||
Severity::information,
|
Severity::information,
|
||||||
"leakconfiguration",
|
"leakconfiguration",
|
||||||
|
@ -104,81 +104,6 @@ void CheckLeakAutoVar::configurationInfo(const Token* tok, const std::string &fu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::parseConfigurationFile(const std::string &filename)
|
|
||||||
{
|
|
||||||
std::ifstream fin(filename.c_str());
|
|
||||||
if (!fin.is_open())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string line;
|
|
||||||
while (std::getline(fin,line)) {
|
|
||||||
if (line.compare(0,4,"MEM ",0,4) == 0) {
|
|
||||||
std::string f1;
|
|
||||||
enum {ALLOC, DEALLOC} type = ALLOC;
|
|
||||||
std::string::size_type pos1 = line.find_first_not_of(" ", 4U);
|
|
||||||
while (pos1 < line.size()) {
|
|
||||||
const std::string::size_type pos2 = line.find(" ", pos1);
|
|
||||||
std::string f;
|
|
||||||
if (pos2 == std::string::npos)
|
|
||||||
f = line.substr(pos1);
|
|
||||||
else
|
|
||||||
f = line.substr(pos1, pos2-pos1);
|
|
||||||
if (f1.empty())
|
|
||||||
f1 = f;
|
|
||||||
if (f == ":")
|
|
||||||
type = DEALLOC;
|
|
||||||
else if (type == ALLOC)
|
|
||||||
cfgalloc[f] = f1;
|
|
||||||
else if (type == DEALLOC)
|
|
||||||
cfgdealloc[f] = f1;
|
|
||||||
pos1 = line.find_first_not_of(" ", pos2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (line.compare(0,7,"IGNORE ",0,7) == 0) {
|
|
||||||
std::string::size_type pos1 = line.find_first_not_of(" ", 7U);
|
|
||||||
while (pos1 < line.size()) {
|
|
||||||
std::string::size_type pos2 = line.find_first_of(" ", pos1);
|
|
||||||
std::string functionName;
|
|
||||||
if (pos2 == std::string::npos)
|
|
||||||
functionName = line.substr(pos1);
|
|
||||||
else
|
|
||||||
functionName = line.substr(pos1, pos2-pos1);
|
|
||||||
cfgignore.insert(functionName);
|
|
||||||
pos1 = line.find_first_not_of(" ", pos2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (line.compare(0,4,"USE ",0,4) == 0) {
|
|
||||||
std::string::size_type pos1 = line.find_first_not_of(" ", 4U);
|
|
||||||
while (pos1 < line.size()) {
|
|
||||||
std::string::size_type pos2 = line.find_first_of(" ", pos1);
|
|
||||||
std::string functionName;
|
|
||||||
if (pos2 == std::string::npos)
|
|
||||||
functionName = line.substr(pos1);
|
|
||||||
else
|
|
||||||
functionName = line.substr(pos1, pos2-pos1);
|
|
||||||
cfguse.insert(functionName);
|
|
||||||
pos1 = line.find_first_not_of(" ", pos2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (line.compare(0,9,"NORETURN ",0,9) == 0) {
|
|
||||||
std::string::size_type pos1 = line.find_first_not_of(" ", 9U);
|
|
||||||
while (pos1 < line.size()) {
|
|
||||||
std::string::size_type pos2 = line.find_first_of(" ", pos1);
|
|
||||||
std::string functionName;
|
|
||||||
if (pos2 == std::string::npos)
|
|
||||||
functionName = line.substr(pos1);
|
|
||||||
else
|
|
||||||
functionName = line.substr(pos1, pos2-pos1);
|
|
||||||
cfgnoreturn.insert(functionName);
|
|
||||||
pos1 = line.find_first_not_of(" ", pos2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckLeakAutoVar::check()
|
void CheckLeakAutoVar::check()
|
||||||
{
|
{
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
@ -198,7 +123,7 @@ void CheckLeakAutoVar::check()
|
||||||
varInfo.conditionalAlloc.clear();
|
varInfo.conditionalAlloc.clear();
|
||||||
|
|
||||||
// Clear reference arguments from varInfo..
|
// Clear reference arguments from varInfo..
|
||||||
std::map<unsigned int, std::string>::iterator it = varInfo.alloctype.begin();
|
std::map<unsigned int, int>::iterator it = varInfo.alloctype.begin();
|
||||||
while (it != varInfo.alloctype.end()) {
|
while (it != varInfo.alloctype.end()) {
|
||||||
const Variable *var = symbolDatabase->getVariableFromVarId(it->first);
|
const Variable *var = symbolDatabase->getVariableFromVarId(it->first);
|
||||||
if (!var ||
|
if (!var ||
|
||||||
|
@ -217,29 +142,18 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
VarInfo *varInfo,
|
VarInfo *varInfo,
|
||||||
std::set<unsigned int> notzero)
|
std::set<unsigned int> notzero)
|
||||||
{
|
{
|
||||||
std::map<unsigned int, std::string> &alloctype = varInfo->alloctype;
|
std::map<unsigned int, int> &alloctype = varInfo->alloctype;
|
||||||
std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage;
|
std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage;
|
||||||
const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc);
|
const std::set<unsigned int> conditionalAlloc(varInfo->conditionalAlloc);
|
||||||
|
|
||||||
// Allocation functions. key = function name, value = allocation type
|
|
||||||
std::map<std::string, std::string> allocFunctions(cfgalloc);
|
|
||||||
allocFunctions["malloc"] = "malloc";
|
|
||||||
allocFunctions["strdup"] = "malloc";
|
|
||||||
allocFunctions["fopen"] = "fopen";
|
|
||||||
|
|
||||||
// Deallocation functions. key = function name, value = allocation type
|
|
||||||
std::map<std::string, std::string> deallocFunctions(cfgdealloc);
|
|
||||||
deallocFunctions["free"] = "malloc";
|
|
||||||
deallocFunctions["fclose"] = "fopen";
|
|
||||||
|
|
||||||
// Parse all tokens
|
// Parse all tokens
|
||||||
const Token * const endToken = startToken->link();
|
const Token * const endToken = startToken->link();
|
||||||
for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) {
|
for (const Token *tok = startToken; tok && tok != endToken; tok = tok->next()) {
|
||||||
// Deallocation and then dereferencing pointer..
|
// Deallocation and then dereferencing pointer..
|
||||||
if (tok->varId() > 0) {
|
if (tok->varId() > 0) {
|
||||||
const std::map<unsigned int, std::string>::iterator var = alloctype.find(tok->varId());
|
const std::map<unsigned int, int>::iterator var = alloctype.find(tok->varId());
|
||||||
if (var != alloctype.end()) {
|
if (var != alloctype.end()) {
|
||||||
if (var->second == "dealloc" && !Token::Match(tok->previous(), "[;{},=] %var% =")) {
|
if (var->second == DEALLOC && !Token::Match(tok->previous(), "[;{},=] %var% =")) {
|
||||||
deallocUseError(tok, tok->str());
|
deallocUseError(tok, tok->str());
|
||||||
} else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
|
} else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
|
||||||
varInfo->erase(tok->varId());
|
varInfo->erase(tok->varId());
|
||||||
|
@ -252,7 +166,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->str() == "(" && tok->previous()->isName()) {
|
if (tok->str() == "(" && tok->previous()->isName()) {
|
||||||
functionCall(tok->previous(), varInfo, "");
|
functionCall(tok->previous(), varInfo, NOALLOC);
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -318,9 +232,9 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
|
|
||||||
// allocation?
|
// allocation?
|
||||||
if (Token::Match(tok->tokAt(2), "%type% (")) {
|
if (Token::Match(tok->tokAt(2), "%type% (")) {
|
||||||
const std::map<std::string, std::string>::const_iterator it = allocFunctions.find(tok->strAt(2));
|
int i = _settings->environment.alloc(tok->strAt(2));
|
||||||
if (it != allocFunctions.end()) {
|
if (i > 0) {
|
||||||
alloctype[tok->varId()] = it->second;
|
alloctype[tok->varId()] = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,15 +255,8 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
if (innerTok->str() == ")")
|
if (innerTok->str() == ")")
|
||||||
break;
|
break;
|
||||||
if (innerTok->str() == "(" && innerTok->previous()->isName()) {
|
if (innerTok->str() == "(" && innerTok->previous()->isName()) {
|
||||||
std::string dealloc;
|
const int deallocId = _settings->environment.dealloc(tok->str());
|
||||||
{
|
functionCall(innerTok->previous(), varInfo, deallocId);
|
||||||
const std::map<std::string, std::string>::iterator func = deallocFunctions.find(tok->str());
|
|
||||||
if (func != deallocFunctions.end()) {
|
|
||||||
dealloc = func->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
functionCall(innerTok->previous(), varInfo, dealloc);
|
|
||||||
innerTok = innerTok->link();
|
innerTok = innerTok->link();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,7 +289,7 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
old.swap(*varInfo);
|
old.swap(*varInfo);
|
||||||
|
|
||||||
// Conditional allocation in varInfo1
|
// Conditional allocation in varInfo1
|
||||||
std::map<unsigned int, std::string>::const_iterator it;
|
std::map<unsigned int, int>::const_iterator it;
|
||||||
for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
|
for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
|
||||||
if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() &&
|
if (varInfo2.alloctype.find(it->first) == varInfo2.alloctype.end() &&
|
||||||
old.alloctype.find(it->first) == old.alloctype.end()) {
|
old.alloctype.find(it->first) == old.alloctype.end()) {
|
||||||
|
@ -400,13 +307,13 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
|
|
||||||
// Conditional allocation/deallocation
|
// Conditional allocation/deallocation
|
||||||
for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
|
for (it = varInfo1.alloctype.begin(); it != varInfo1.alloctype.end(); ++it) {
|
||||||
if (it->second == "dealloc" && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
|
if (it->second == DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
|
||||||
varInfo->conditionalAlloc.erase(it->first);
|
varInfo->conditionalAlloc.erase(it->first);
|
||||||
varInfo2.erase(it->first);
|
varInfo2.erase(it->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
|
for (it = varInfo2.alloctype.begin(); it != varInfo2.alloctype.end(); ++it) {
|
||||||
if (it->second == "dealloc" && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
|
if (it->second == DEALLOC && conditionalAlloc.find(it->first) != conditionalAlloc.end()) {
|
||||||
varInfo->conditionalAlloc.erase(it->first);
|
varInfo->conditionalAlloc.erase(it->first);
|
||||||
varInfo1.erase(it->first);
|
varInfo1.erase(it->first);
|
||||||
}
|
}
|
||||||
|
@ -428,24 +335,18 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
|
|
||||||
// Function call..
|
// Function call..
|
||||||
else if (Token::Match(tok, "%type% (") && tok->str() != "return") {
|
else if (Token::Match(tok, "%type% (") && tok->str() != "return") {
|
||||||
std::string dealloc;
|
const int dealloc = _settings->environment.dealloc(tok->str());
|
||||||
{
|
|
||||||
const std::map<std::string, std::string>::iterator func = deallocFunctions.find(tok->str());
|
|
||||||
if (func != deallocFunctions.end()) {
|
|
||||||
dealloc = func->second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
functionCall(tok, varInfo, dealloc);
|
functionCall(tok, varInfo, dealloc);
|
||||||
|
|
||||||
tok = tok->next()->link();
|
tok = tok->next()->link();
|
||||||
|
|
||||||
// Handle scopes that might be noreturn
|
// Handle scopes that might be noreturn
|
||||||
if (dealloc.empty() && Token::simpleMatch(tok, ") ; }")) {
|
if (dealloc == NOALLOC && Token::simpleMatch(tok, ") ; }")) {
|
||||||
const std::string &functionName(tok->link()->previous()->str());
|
const std::string &functionName(tok->link()->previous()->str());
|
||||||
bool unknown = false;
|
bool unknown = false;
|
||||||
if (cfgignore.find(functionName) == cfgignore.end() &&
|
if (_settings->environment.ignore.find(functionName) == _settings->environment.ignore.end() &&
|
||||||
cfguse.find(functionName) == cfguse.end() &&
|
_settings->environment.use.find(functionName) == _settings->environment.use.end() &&
|
||||||
_tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) {
|
_tokenizer->IsScopeNoReturn(tok->tokAt(2), &unknown)) {
|
||||||
if (unknown) {
|
if (unknown) {
|
||||||
//const std::string &functionName(tok->link()->previous()->str());
|
//const std::string &functionName(tok->link()->previous()->str());
|
||||||
|
@ -478,14 +379,13 @@ void CheckLeakAutoVar::checkScope(const Token * const startToken,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const std::string &dealloc)
|
void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const int dealloc)
|
||||||
{
|
{
|
||||||
std::map<unsigned int, std::string> &alloctype = varInfo->alloctype;
|
std::map<unsigned int, int> &alloctype = varInfo->alloctype;
|
||||||
std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage;
|
std::map<unsigned int, std::string> &possibleUsage = varInfo->possibleUsage;
|
||||||
|
|
||||||
// Ignore function call?
|
// Ignore function call?
|
||||||
const bool ignore = bool(cfgignore.find(tok->str()) != cfgignore.end());
|
const bool ignore = bool(_settings->environment.ignore.find(tok->str()) != _settings->environment.ignore.end());
|
||||||
//const bool use = bool(cfguse.find(tok->str()) != cfguse.end());
|
|
||||||
|
|
||||||
if (ignore)
|
if (ignore)
|
||||||
return;
|
return;
|
||||||
|
@ -499,14 +399,14 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const st
|
||||||
arg = arg->next();
|
arg = arg->next();
|
||||||
|
|
||||||
// Is variable allocated?
|
// Is variable allocated?
|
||||||
const std::map<unsigned int,std::string>::iterator var = alloctype.find(arg->varId());
|
const std::map<unsigned int,int>::iterator var = alloctype.find(arg->varId());
|
||||||
if (var != alloctype.end()) {
|
if (var != alloctype.end()) {
|
||||||
if (dealloc.empty()) {
|
if (dealloc == NOALLOC) {
|
||||||
// possible usage
|
// possible usage
|
||||||
possibleUsage[arg->varId()] = tok->str();
|
possibleUsage[arg->varId()] = tok->str();
|
||||||
if (var->second == "dealloc" && arg->previous()->str() == "&")
|
if (var->second == DEALLOC && arg->previous()->str() == "&")
|
||||||
varInfo->erase(arg->varId());
|
varInfo->erase(arg->varId());
|
||||||
} else if (var->second == "dealloc") {
|
} else if (var->second == DEALLOC) {
|
||||||
CheckOther checkOther(_tokenizer, _settings, _errorLogger);
|
CheckOther checkOther(_tokenizer, _settings, _errorLogger);
|
||||||
checkOther.doubleFreeError(tok, arg->str());
|
checkOther.doubleFreeError(tok, arg->str());
|
||||||
} else if (var->second != dealloc) {
|
} else if (var->second != dealloc) {
|
||||||
|
@ -515,10 +415,10 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const st
|
||||||
varInfo->erase(arg->varId());
|
varInfo->erase(arg->varId());
|
||||||
} else {
|
} else {
|
||||||
// deallocation
|
// deallocation
|
||||||
var->second = "dealloc";
|
var->second = DEALLOC;
|
||||||
}
|
}
|
||||||
} else if (!dealloc.empty()) {
|
} else if (dealloc != NOALLOC) {
|
||||||
alloctype[arg->varId()] = "dealloc";
|
alloctype[arg->varId()] = DEALLOC;
|
||||||
}
|
}
|
||||||
} else if (Token::Match(arg, "%var% (")) {
|
} else if (Token::Match(arg, "%var% (")) {
|
||||||
functionCall(arg, varInfo, dealloc);
|
functionCall(arg, varInfo, dealloc);
|
||||||
|
@ -530,11 +430,11 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const st
|
||||||
void CheckLeakAutoVar::leakIfAllocated(const Token *vartok,
|
void CheckLeakAutoVar::leakIfAllocated(const Token *vartok,
|
||||||
const VarInfo &varInfo)
|
const VarInfo &varInfo)
|
||||||
{
|
{
|
||||||
const std::map<unsigned int, std::string> &alloctype = varInfo.alloctype;
|
const std::map<unsigned int, int> &alloctype = varInfo.alloctype;
|
||||||
const std::map<unsigned int, std::string> &possibleUsage = varInfo.possibleUsage;
|
const std::map<unsigned int, std::string> &possibleUsage = varInfo.possibleUsage;
|
||||||
|
|
||||||
const std::map<unsigned int,std::string>::const_iterator var = alloctype.find(vartok->varId());
|
const std::map<unsigned int,int>::const_iterator var = alloctype.find(vartok->varId());
|
||||||
if (var != alloctype.end() && var->second != "dealloc") {
|
if (var != alloctype.end() && var->second != DEALLOC) {
|
||||||
const std::map<unsigned int, std::string>::const_iterator use = possibleUsage.find(vartok->varId());
|
const std::map<unsigned int, std::string>::const_iterator use = possibleUsage.find(vartok->varId());
|
||||||
if (use == possibleUsage.end()) {
|
if (use == possibleUsage.end()) {
|
||||||
leakError(vartok, vartok->str(), var->second);
|
leakError(vartok, vartok->str(), var->second);
|
||||||
|
@ -546,13 +446,13 @@ void CheckLeakAutoVar::leakIfAllocated(const Token *vartok,
|
||||||
|
|
||||||
void CheckLeakAutoVar::ret(const Token *tok, const VarInfo &varInfo)
|
void CheckLeakAutoVar::ret(const Token *tok, const VarInfo &varInfo)
|
||||||
{
|
{
|
||||||
const std::map<unsigned int, std::string> &alloctype = varInfo.alloctype;
|
const std::map<unsigned int, int> &alloctype = varInfo.alloctype;
|
||||||
const std::map<unsigned int, std::string> &possibleUsage = varInfo.possibleUsage;
|
const std::map<unsigned int, std::string> &possibleUsage = varInfo.possibleUsage;
|
||||||
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
for (std::map<unsigned int, std::string>::const_iterator it = alloctype.begin(); it != alloctype.end(); ++it) {
|
for (std::map<unsigned int, int>::const_iterator it = alloctype.begin(); it != alloctype.end(); ++it) {
|
||||||
// don't warn if variable is conditionally allocated
|
// don't warn if variable is conditionally allocated
|
||||||
if (it->second != "dealloc" && varInfo.conditionalAlloc.find(it->first) != varInfo.conditionalAlloc.end())
|
if (it->second != DEALLOC && varInfo.conditionalAlloc.find(it->first) != varInfo.conditionalAlloc.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// don't warn if there is a reference of the variable
|
// don't warn if there is a reference of the variable
|
||||||
|
@ -577,10 +477,10 @@ void CheckLeakAutoVar::ret(const Token *tok, const VarInfo &varInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return deallocated pointer
|
// return deallocated pointer
|
||||||
if (used && it->second == "dealloc")
|
if (used && it->second == DEALLOC)
|
||||||
deallocReturnError(tok, var->name());
|
deallocReturnError(tok, var->name());
|
||||||
|
|
||||||
else if (!used && it->second != "dealloc") {
|
else if (!used && it->second != DEALLOC) {
|
||||||
|
|
||||||
const std::map<unsigned int, std::string>::const_iterator use = possibleUsage.find(varid);
|
const std::map<unsigned int, std::string>::const_iterator use = possibleUsage.find(varid);
|
||||||
if (use == possibleUsage.end()) {
|
if (use == possibleUsage.end()) {
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
class CPPCHECKLIB VarInfo {
|
class CPPCHECKLIB VarInfo {
|
||||||
public:
|
public:
|
||||||
std::map<unsigned int, std::string> alloctype;
|
std::map<unsigned int, int> alloctype;
|
||||||
std::map<unsigned int, std::string> possibleUsage;
|
std::map<unsigned int, std::string> possibleUsage;
|
||||||
std::set<unsigned int> conditionalAlloc;
|
std::set<unsigned int> conditionalAlloc;
|
||||||
std::set<unsigned int> referenced;
|
std::set<unsigned int> referenced;
|
||||||
|
@ -81,20 +81,11 @@ public:
|
||||||
/** @brief Run checks against the simplified token list */
|
/** @brief Run checks against the simplified token list */
|
||||||
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) {
|
||||||
CheckLeakAutoVar checkLeakAutoVar(tokenizer, settings, errorLogger);
|
CheckLeakAutoVar checkLeakAutoVar(tokenizer, settings, errorLogger);
|
||||||
checkLeakAutoVar.parseConfigurationFile("cppcheck.cfg");
|
|
||||||
checkLeakAutoVar.check();
|
checkLeakAutoVar.check();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::map<std::string,std::string> cfgalloc;
|
|
||||||
std::map<std::string,std::string> cfgdealloc;
|
|
||||||
std::set<std::string> cfgignore;
|
|
||||||
std::set<std::string> cfguse;
|
|
||||||
std::set<std::string> cfgnoreturn;
|
|
||||||
|
|
||||||
void parseConfigurationFile(const std::string &filename);
|
|
||||||
|
|
||||||
/** check for leaks in all scopes */
|
/** check for leaks in all scopes */
|
||||||
void check();
|
void check();
|
||||||
|
|
||||||
|
@ -104,7 +95,7 @@ private:
|
||||||
std::set<unsigned int> notzero);
|
std::set<unsigned int> notzero);
|
||||||
|
|
||||||
/** parse function call */
|
/** parse function call */
|
||||||
void functionCall(const Token *tok, VarInfo *varInfo, const std::string &dealloc);
|
void functionCall(const Token *tok, VarInfo *varInfo, const int dealloc);
|
||||||
|
|
||||||
/** return. either "return" or end of variable scope is seen */
|
/** return. either "return" or end of variable scope is seen */
|
||||||
void ret(const Token *tok, const VarInfo &varInfo);
|
void ret(const Token *tok, const VarInfo &varInfo);
|
||||||
|
@ -112,7 +103,7 @@ private:
|
||||||
/** if variable is allocated then there is a leak */
|
/** if variable is allocated then there is a leak */
|
||||||
void leakIfAllocated(const Token *vartok, const VarInfo &varInfo);
|
void leakIfAllocated(const Token *vartok, const VarInfo &varInfo);
|
||||||
|
|
||||||
void leakError(const Token* tok, const std::string &varname, const std::string &type);
|
void leakError(const Token* tok, const std::string &varname, int type);
|
||||||
void mismatchError(const Token* tok, const std::string &varname);
|
void mismatchError(const Token* tok, const std::string &varname);
|
||||||
void deallocUseError(const Token *tok, const std::string &varname);
|
void deallocUseError(const Token *tok, const std::string &varname);
|
||||||
void deallocReturnError(const Token *tok, const std::string &varname);
|
void deallocReturnError(const Token *tok, const std::string &varname);
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Cppcheck - A tool for static C/C++ code analysis
|
||||||
|
* Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "environment.h"
|
||||||
|
#include <tinyxml2.h>
|
||||||
|
|
||||||
|
Environment::Environment() : allocid(0)
|
||||||
|
{
|
||||||
|
while (!ismemory(++allocid));
|
||||||
|
_alloc["malloc"] = allocid;
|
||||||
|
_alloc["calloc"] = allocid;
|
||||||
|
_alloc["strdup"] = allocid;
|
||||||
|
_alloc["strndup"] = allocid;
|
||||||
|
_dealloc["free"] = allocid;
|
||||||
|
|
||||||
|
while (!isresource(++allocid));
|
||||||
|
_alloc["fopen"] = allocid;
|
||||||
|
_dealloc["fclose"] = allocid;
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::Environment(const Environment &env) : use(env.use), ignore(env.ignore), noreturn(env.noreturn), allocid(env.allocid), _alloc(env._alloc), _dealloc(env._dealloc)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment::~Environment() { }
|
||||||
|
|
||||||
|
bool Environment::load(const char path[])
|
||||||
|
{
|
||||||
|
tinyxml2::XMLDocument doc;
|
||||||
|
|
||||||
|
const tinyxml2::XMLError error = doc.LoadFile(path);
|
||||||
|
if (error != tinyxml2::XML_NO_ERROR)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const tinyxml2::XMLElement * const rootnode = doc.FirstChildElement();
|
||||||
|
if (strcmp(rootnode->Value(),"def") != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (const tinyxml2::XMLElement *node = rootnode->FirstChildElement(); node; node = node->NextSiblingElement()) {
|
||||||
|
if (strcmp(node->Value(),"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());
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (strcmp(node->Value(),"ignore")==0)
|
||||||
|
ignore.insert(node->GetText());
|
||||||
|
else if (strcmp(node->Value(),"noreturn")==0)
|
||||||
|
noreturn.insert(node->GetText());
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Cppcheck - A tool for static C/C++ code analysis
|
||||||
|
* Copyright (C) 2007-2013 Daniel Marjamäki and Cppcheck team.
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ENVIRONMENT_H
|
||||||
|
#define ENVIRONMENT_H
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/// @addtogroup Core
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Environment definitions handling
|
||||||
|
*/
|
||||||
|
class Environment {
|
||||||
|
public:
|
||||||
|
Environment();
|
||||||
|
Environment(const Environment &);
|
||||||
|
~Environment();
|
||||||
|
|
||||||
|
bool load(const char path[]);
|
||||||
|
|
||||||
|
/** get allocation id for function (by name) */
|
||||||
|
int alloc(const std::string &name) const {
|
||||||
|
return getid(_alloc, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** get deallocation id for function (by name) */
|
||||||
|
int dealloc(const std::string &name) const {
|
||||||
|
return getid(_dealloc, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** is allocation type memory? */
|
||||||
|
static bool ismemory(int id) {
|
||||||
|
return ((id > 0) && ((id & 1) == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** is allocation type resource? */
|
||||||
|
static bool isresource(int id) {
|
||||||
|
return ((id > 0) && ((id & 1) == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::set<std::string> use;
|
||||||
|
std::set<std::string> ignore;
|
||||||
|
std::set<std::string> noreturn;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int allocid;
|
||||||
|
std::map<std::string, int> _alloc; // allocation functions
|
||||||
|
std::map<std::string, int> _dealloc; // deallocation functions
|
||||||
|
|
||||||
|
int getid(const std::map<std::string,int> &data, const std::string &name) const {
|
||||||
|
const std::map<std::string,int>::const_iterator it = data.find(name);
|
||||||
|
return (it == data.end()) ? 0 : it->second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
#endif // PATH_H_INCLUDED
|
|
@ -27,6 +27,7 @@ HEADERS += $${BASEPATH}check.h \
|
||||||
$${BASEPATH}checkunusedfunctions.h \
|
$${BASEPATH}checkunusedfunctions.h \
|
||||||
$${BASEPATH}checkunusedvar.h \
|
$${BASEPATH}checkunusedvar.h \
|
||||||
$${BASEPATH}cppcheck.h \
|
$${BASEPATH}cppcheck.h \
|
||||||
|
$${BASEPATH}environment.h \
|
||||||
$${BASEPATH}errorlogger.h \
|
$${BASEPATH}errorlogger.h \
|
||||||
$${BASEPATH}executionpath.h \
|
$${BASEPATH}executionpath.h \
|
||||||
$${BASEPATH}mathlib.h \
|
$${BASEPATH}mathlib.h \
|
||||||
|
@ -66,6 +67,7 @@ SOURCES += $${BASEPATH}check64bit.cpp \
|
||||||
$${BASEPATH}checkunusedfunctions.cpp \
|
$${BASEPATH}checkunusedfunctions.cpp \
|
||||||
$${BASEPATH}checkunusedvar.cpp \
|
$${BASEPATH}checkunusedvar.cpp \
|
||||||
$${BASEPATH}cppcheck.cpp \
|
$${BASEPATH}cppcheck.cpp \
|
||||||
|
$${BASEPATH}environment.cpp \
|
||||||
$${BASEPATH}errorlogger.cpp \
|
$${BASEPATH}errorlogger.cpp \
|
||||||
$${BASEPATH}executionpath.cpp \
|
$${BASEPATH}executionpath.cpp \
|
||||||
$${BASEPATH}mathlib.cpp \
|
$${BASEPATH}mathlib.cpp \
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "environment.h"
|
||||||
#include "suppressions.h"
|
#include "suppressions.h"
|
||||||
#include "standards.h"
|
#include "standards.h"
|
||||||
|
|
||||||
|
@ -174,6 +175,9 @@ public:
|
||||||
/** @brief --report-progress */
|
/** @brief --report-progress */
|
||||||
bool reportProgress;
|
bool reportProgress;
|
||||||
|
|
||||||
|
/** Environment (--environment) */
|
||||||
|
Environment environment;
|
||||||
|
|
||||||
/** Rule */
|
/** Rule */
|
||||||
class CPPCHECKLIB Rule {
|
class CPPCHECKLIB Rule {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -119,6 +119,7 @@ private:
|
||||||
// Check for leaks..
|
// Check for leaks..
|
||||||
CheckLeakAutoVar c;
|
CheckLeakAutoVar c;
|
||||||
settings.experimental = true;
|
settings.experimental = true;
|
||||||
|
settings.addEnabled("information");
|
||||||
c.runSimplifiedChecks(&tokenizer, &settings, this);
|
c.runSimplifiedChecks(&tokenizer, &settings, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -321,7 +321,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
makeConditionalVariable(fout, "CXX", "g++");
|
makeConditionalVariable(fout, "CXX", "g++");
|
||||||
makeConditionalVariable(fout, "PREFIX", "/usr");
|
makeConditionalVariable(fout, "PREFIX", "/usr");
|
||||||
makeConditionalVariable(fout, "INCLUDE_FOR_LIB", "-Ilib");
|
makeConditionalVariable(fout, "INCLUDE_FOR_LIB", "-Ilib -Iexternals -Iexternals/tinyxml");
|
||||||
makeConditionalVariable(fout, "INCLUDE_FOR_CLI", "-Ilib -Iexternals -Iexternals/tinyxml");
|
makeConditionalVariable(fout, "INCLUDE_FOR_CLI", "-Ilib -Iexternals -Iexternals/tinyxml");
|
||||||
makeConditionalVariable(fout, "INCLUDE_FOR_TEST", "-Ilib -Icli -Iexternals -Iexternals/tinyxml");
|
makeConditionalVariable(fout, "INCLUDE_FOR_TEST", "-Ilib -Icli -Iexternals -Iexternals/tinyxml");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue