errmsg: refactoring the error messages

This commit is contained in:
Daniel Marjamäki 2009-02-01 15:47:36 +00:00
parent 566e1102bc
commit d29d7e60a9
9 changed files with 188 additions and 154 deletions

View File

@ -49,15 +49,11 @@ CheckBufferOverrunClass::~CheckBufferOverrunClass()
}
// Modified version of 'ReportError' that also reports the callstack
void CheckBufferOverrunClass::ReportError(const std::string &errmsg)
void CheckBufferOverrunClass::arrayIndexOutOfBounds(const Token *tok)
{
std::ostringstream ostr;
std::list<const Token *>::const_iterator it;
for (it = _callStack.begin(); it != _callStack.end(); it++)
ostr << _tokenizer->fileLine(*it) << " -> ";
ostr << errmsg;
_errorLogger->reportErr(ostr.str());
_callStack.push_back(tok);
ErrorMessage::arrayIndexOutOfBounds(_errorLogger, _tokenizer, _callStack);
_callStack.pop_back();
}
//---------------------------------------------------------------------------
@ -94,7 +90,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(2);
if (std::strtol(num, NULL, 10) >= size)
{
ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
arrayIndexOutOfBounds(tok->next());
}
}
}
@ -103,7 +99,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(2 + varc);
if (std::strtol(num, NULL, 10) >= size)
{
ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
arrayIndexOutOfBounds(tok->next());
}
}
@ -131,7 +127,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(3);
if (std::strtol(num, NULL, 10) >= size)
{
ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
arrayIndexOutOfBounds(tok->next());
}
}
}
@ -140,7 +136,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->next()->strAt(2 + varc);
if (std::strtol(num, NULL, 10) >= size)
{
ReportError(ErrorMessage::arrayIndexOutOfBounds(_tokenizer, tok->next()));
arrayIndexOutOfBounds(tok->next());
}
tok = tok->tokAt(4);
continue;
@ -158,7 +154,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(6);
if (std::atoi(num) > total_size)
{
ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok));
ErrorMessage::bufferOverrun(_errorLogger, _tokenizer, tok);
}
}
continue;
@ -172,7 +168,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
const char *num = tok->strAt(varc + 6);
if (std::atoi(num) > total_size)
{
ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok));
ErrorMessage::bufferOverrun(_errorLogger, _tokenizer, tok);
}
}
continue;
@ -231,7 +227,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
if (Token::Match(tok2, pattern.str().c_str()))
{
ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok2));
ErrorMessage::bufferOverrun(_errorLogger, _tokenizer, tok2);
break;
}
@ -254,7 +250,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
}
if (len > 2 && len >= (int)size + 2)
{
ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok));
ErrorMessage::bufferOverrun(_errorLogger, _tokenizer, tok);
}
continue;
}
@ -280,7 +276,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
}
if (len > (int)size)
{
ReportError(ErrorMessage::bufferOverrun(_tokenizer, tok));
ErrorMessage::bufferOverrun(_errorLogger, _tokenizer, tok);
}
}
@ -289,7 +285,7 @@ void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope(const Token *tok, co
{
int n = std::atoi(tok->strAt(4));
if (n > size)
ReportError(ErrorMessage::outOfBounds(_tokenizer, tok->tokAt(4), "snprintf size"));
ErrorMessage::outOfBounds(_errorLogger, _tokenizer, tok->tokAt(4), "snprintf size");
}

View File

@ -45,15 +45,14 @@ private:
/** Check for buffer overruns - this is the function that performs the actual checking */
void CheckBufferOverrun_CheckScope(const Token *tok, const char *varname[], const int size, const int total_size, unsigned int varid);
/** Report error using the callstack */
void ReportError(const std::string &errmsg);
const Tokenizer *_tokenizer;
const Settings _settings;
ErrorLogger *_errorLogger;
/** callstack - used during intra-function checking */
std::list<const Token *> _callStack;
void arrayIndexOutOfBounds(const Token *tok);
};
//---------------------------------------------------------------------------

View File

@ -387,7 +387,7 @@ void CheckClass::constructors()
struct VAR *varlist = ClassChecking_GetVarList(tok1);
if (varlist)
{
_errorLogger->reportErr(ErrorMessage::noConstructor(_tokenizer, tok1, classNameToken->str()));
ErrorMessage::noConstructor(_errorLogger, _tokenizer, tok1, classNameToken->str());
}
// Delete the varlist..
while (varlist)
@ -446,7 +446,7 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const
continue;
// It's non-static and it's not initialized => error
_errorLogger->reportErr(ErrorMessage::uninitVar(_tokenizer, constructor_token, className, var->name));
ErrorMessage::uninitVar(_errorLogger, _tokenizer, constructor_token, className, var->name);
}
for (struct VAR *var = varlist; var; var = var->next)
@ -577,7 +577,7 @@ void CheckClass::privateFunctions()
const std::string _pattern("return|(|)|,|= " + FuncList.front()->str());
if (!Token::findmatch(_tokenizer->tokens(), _pattern.c_str()))
{
_errorLogger->reportErr(ErrorMessage::unusedPrivateFunction(_tokenizer, FuncList.front(), classname, FuncList.front()->str()));
ErrorMessage::unusedPrivateFunction(_errorLogger, _tokenizer, FuncList.front(), classname, FuncList.front()->str());
}
FuncList.pop_front();
}
@ -617,7 +617,7 @@ void CheckClass::noMemset()
const std::string pattern1(std::string("class ") + type);
if (Token::findmatch(_tokenizer->tokens(), pattern1.c_str()))
{
_errorLogger->reportErr(ErrorMessage::memsetClass(_tokenizer, tok, tok->str()));
ErrorMessage::memsetClass(_errorLogger, _tokenizer, tok, tok->str());
continue;
}
@ -630,7 +630,7 @@ void CheckClass::noMemset()
if (Token::Match(tstruct, "std :: %type% %var% ;"))
{
_errorLogger->reportErr(ErrorMessage::memsetStruct(_tokenizer, tok, tok->str(), tstruct->strAt(2)));
ErrorMessage::memsetStruct(_errorLogger, _tokenizer, tok, tok->str(), tstruct->strAt(2));
break;
}
}
@ -650,7 +650,7 @@ void CheckClass::operatorEq()
const Token *tok = Token::findmatch(_tokenizer->tokens(), "void operator = (");
if (tok)
{
_errorLogger->reportErr(ErrorMessage::operatorEq(_tokenizer, tok));
ErrorMessage::operatorEq(_errorLogger, _tokenizer, tok);
}
}
//---------------------------------------------------------------------------
@ -731,14 +731,14 @@ void CheckClass::virtualDestructor()
base = Token::findmatch(_tokenizer->tokens(), (std::string("class ") + baseName[0] + " :|{").c_str());
if (base)
{
_errorLogger->reportErr(ErrorMessage::virtualDestructor(_tokenizer, base, baseName[0], derivedClass->str()));
ErrorMessage::virtualDestructor(_errorLogger, _tokenizer, base, baseName[0], derivedClass->str());
}
}
// There is a destructor. Check that it's virtual..
else if (base->str() != "virtual")
{
_errorLogger->reportErr(ErrorMessage::virtualDestructor(_tokenizer, base, baseName[0], derivedClass->str()));
ErrorMessage::virtualDestructor(_errorLogger, _tokenizer, base, baseName[0], derivedClass->str());
}
}
}

View File

@ -158,7 +158,7 @@ void CheckFunctionUsage::check()
filename = "";
else
filename = func.filename;
_errorLogger->reportErr(ErrorMessage::unusedFunction(filename, it->first));
ErrorMessage::unusedFunction(_errorLogger, filename, it->first);
}
else if (! func.usedOtherFile)
{

View File

@ -291,27 +291,15 @@ const char * CheckMemoryLeakClass::call_func(const Token *tok, std::list<const T
//--------------------------------------------------------------------------
void CheckMemoryLeakClass::MismatchError(const Token *Tok1, const std::list<const Token *> &callstack, const char varname[])
{
if (! ErrorMessage::mismatchAllocDealloc(_settings))
return;
std::ostringstream errmsg;
for (std::list<const Token *>::const_iterator tok = callstack.begin(); tok != callstack.end(); ++tok)
errmsg << _tokenizer->fileLine(*tok) << " -> ";
errmsg << ErrorMessage::mismatchAllocDealloc(_tokenizer, Tok1, varname);
_errorLogger->reportErr(errmsg.str());
}
//---------------------------------------------------------------------------
void CheckMemoryLeakClass::MemoryLeak(const Token *tok, const char varname[], AllocType alloctype, bool all)
{
if (alloctype == CheckMemoryLeakClass::FOPEN ||
alloctype == CheckMemoryLeakClass::POPEN)
_errorLogger->reportErr(ErrorMessage::resourceLeak(_tokenizer, tok, varname));
ErrorMessage::resourceLeak(_errorLogger, _tokenizer, tok, varname);
else if (all)
_errorLogger->reportErr(ErrorMessage::memleakall(_tokenizer, tok, varname));
ErrorMessage::memleakall(_errorLogger, _tokenizer, tok, varname);
else
_errorLogger->reportErr(ErrorMessage::memleak(_tokenizer, tok, varname));
ErrorMessage::memleak(_errorLogger, _tokenizer, tok, varname);
}
//---------------------------------------------------------------------------
@ -429,10 +417,13 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list<const Token *>
{
if (! realloc)
addtoken("alloc");
if (alloctype != No && alloctype != alloc)
MismatchError(tok, callstack, varname);
if (dealloctype != No && dealloctype != alloc)
MismatchError(tok, callstack, varname);
if ((alloctype != No && alloctype != alloc) ||
(dealloctype != No && dealloctype != alloc))
{
callstack.push_back(tok);
ErrorMessage::mismatchAllocDealloc(_errorLogger, _tokenizer, callstack, varname);
callstack.pop_back();
}
alloctype = alloc;
}
@ -469,10 +460,13 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list<const Token *>
if (dealloc != No)
{
addtoken("dealloc");
if (alloctype != No && alloctype != dealloc)
MismatchError(tok, callstack, varname);
if (dealloctype != No && dealloctype != dealloc)
MismatchError(tok, callstack, varname);
if ((alloctype != No && alloctype != dealloc) ||
(dealloctype != No && dealloctype != dealloc))
{
callstack.push_back(tok);
ErrorMessage::mismatchAllocDealloc(_errorLogger, _tokenizer, callstack, varname);
callstack.pop_back();
}
dealloctype = dealloc;
continue;
}
@ -1234,7 +1228,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope(const Token *Tok1, const c
else if ((result = Token::findmatch(tok, "dealloc ; dealloc ;")) != NULL)
{
_errorLogger->reportErr(ErrorMessage::deallocDealloc(_tokenizer, result->tokAt(2), varname));
ErrorMessage::deallocDealloc(_errorLogger, _tokenizer, result->tokAt(2), varname);
}
else if (! Token::findmatch(tok, "dealloc") &&
@ -1462,10 +1456,13 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable(const std::vect
if (alloc != No)
{
std::list<const Token *> callstack;
if (Dealloc != No && Dealloc != alloc)
MismatchError(tok, callstack, FullVariableName.str().c_str());
if (Alloc != No && Alloc != alloc)
MismatchError(tok, callstack, FullVariableName.str().c_str());
if ((Dealloc != No && Dealloc != alloc) ||
(Alloc != No && Alloc != alloc))
{
callstack.push_back(tok);
ErrorMessage::mismatchAllocDealloc(_errorLogger, _tokenizer, callstack, FullVariableName.str());
callstack.pop_back();
}
Alloc = alloc;
}
}
@ -1483,10 +1480,13 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable(const std::vect
if (dealloc != No)
{
std::list<const Token *> callstack;
if (Dealloc != No && Dealloc != dealloc)
MismatchError(tok, callstack, FullVariableName.str().c_str());
if (Alloc != No && Alloc != dealloc)
MismatchError(tok, callstack, FullVariableName.str().c_str());
if ((Dealloc != No && Dealloc != dealloc) ||
(Alloc != No && Alloc != dealloc))
{
callstack.push_back(tok);
ErrorMessage::mismatchAllocDealloc(_errorLogger, _tokenizer, callstack, FullVariableName.str());
callstack.pop_back();
}
Dealloc = dealloc;
}

View File

@ -61,7 +61,7 @@ void CheckOther::WarningOldStylePointerCast()
if (!Token::findmatch(_tokenizer->tokens(), pattern.c_str()))
continue;
_errorLogger->reportErr(ErrorMessage::cstyleCast(_tokenizer, tok));
ErrorMessage::cstyleCast(_errorLogger, _tokenizer, tok);
}
}
@ -142,7 +142,7 @@ void CheckOther::WarningRedundantCode()
if (err)
{
_errorLogger->reportErr(ErrorMessage::redundantIfDelete0(_tokenizer, tok));
ErrorMessage::redundantIfDelete0(_errorLogger, _tokenizer, tok);
}
}
@ -178,7 +178,7 @@ void CheckOther::redundantCondition2()
var2->str() == var3->str() &&
any1->str() == any2->str())
{
_errorLogger->reportErr(ErrorMessage::redundantIfRemove(_tokenizer, tok));
ErrorMessage::redundantIfRemove(_errorLogger, _tokenizer, tok);
}
tok = Token::findmatch(tok->next(), pattern);
@ -216,7 +216,7 @@ void CheckOther::WarningIf()
{
if (Token::Match(tok2, ") ; !!else"))
{
_errorLogger->reportErr(ErrorMessage::ifNoAction(_tokenizer, tok));
ErrorMessage::ifNoAction(_errorLogger, _tokenizer, tok);
}
break;
}
@ -279,7 +279,7 @@ void CheckOther::WarningIf()
if (strcmp(cond, p[i]) == 0)
b = (i < 3);
}
_errorLogger->reportErr(ErrorMessage::conditionAlwaysTrueFalse(_tokenizer, tok->tokAt(4), b ? "True" : "False"));
ErrorMessage::conditionAlwaysTrueFalse(_errorLogger, _tokenizer, tok->tokAt(4), b ? "True" : "False");
}
}
}
@ -319,7 +319,7 @@ void CheckOther::InvalidFunctionUsage()
int radix = std::atoi(tok2->strAt(1));
if (!(radix == 0 || (radix >= 2 && radix <= 36)))
{
_errorLogger->reportErr(ErrorMessage::dangerousUsageStrtol(_tokenizer, tok2));
ErrorMessage::dangerousUsageStrtol(_errorLogger, _tokenizer, tok2);
}
}
break;
@ -362,7 +362,7 @@ void CheckOther::InvalidFunctionUsage()
}
else if (parlevel == 0 && Token::Match(tok2, ", %varid% [,)]", varid))
{
_errorLogger->reportErr(ErrorMessage::sprintfOverlappingData(_tokenizer, tok2->next(), _settings, tok2->next()->str()));
ErrorMessage::sprintfOverlappingData(_errorLogger, _tokenizer, tok2->next(), tok2->next()->str());
break;
}
}
@ -403,7 +403,7 @@ void CheckOther::CheckUnsignedDivision()
if (sign1 && sign2 && sign1 != sign2)
{
// One of the operands are signed, the other is unsigned..
_errorLogger->reportErr(ErrorMessage::udivWarning(_tokenizer, tok->next()));
ErrorMessage::udivWarning(_errorLogger, _tokenizer, tok->next());
}
}
}
@ -416,7 +416,7 @@ void CheckOther::CheckUnsignedDivision()
char sign1 = varsign[varname1];
if (sign1 == 'u')
{
_errorLogger->reportErr(ErrorMessage::udivError(_tokenizer, tok->next()));
ErrorMessage::udivError(_errorLogger, _tokenizer, tok->next());
}
}
}
@ -429,7 +429,7 @@ void CheckOther::CheckUnsignedDivision()
char sign2 = varsign[varname2];
if (sign2 == 'u')
{
_errorLogger->reportErr(ErrorMessage::udivError(_tokenizer, tok->next()));
ErrorMessage::udivError(_errorLogger, _tokenizer, tok->next());
}
}
}
@ -587,7 +587,7 @@ void CheckOther::CheckVariableScope_LookupVar(const Token *tok1, const char varn
}
// Warning if "used" is true
_errorLogger->reportErr(ErrorMessage::variableScope(_tokenizer, tok1, varname));
ErrorMessage::variableScope(_errorLogger, _tokenizer, tok1, varname);
}
//---------------------------------------------------------------------------
@ -602,7 +602,7 @@ void CheckOther::CheckConstantFunctionParameter()
{
if (Token::Match(tok, "[,(] const std :: %type% %var% [,)]"))
{
_errorLogger->reportErr(ErrorMessage::passedByValue(_tokenizer, tok, tok->strAt(5)));
ErrorMessage::passedByValue(_errorLogger, _tokenizer, tok, tok->strAt(5));
}
else if (Token::Match(tok, "[,(] const %type% %var% [,)]"))
@ -611,7 +611,7 @@ void CheckOther::CheckConstantFunctionParameter()
const std::string pattern(std::string("class|struct ") + tok->strAt(2));
if (Token::findmatch(_tokenizer->tokens(), pattern.c_str()))
{
_errorLogger->reportErr(ErrorMessage::passedByValue(_tokenizer, tok, tok->strAt(3)));
ErrorMessage::passedByValue(_errorLogger, _tokenizer, tok, tok->strAt(3));
}
}
}
@ -679,7 +679,7 @@ void CheckOther::CheckStructMemberUsage()
if (! used)
{
_errorLogger->reportErr(ErrorMessage::unusedStructMember(_tokenizer, tok->next(), structname, varname));
ErrorMessage::unusedStructMember(_errorLogger, _tokenizer, tok->next(), structname, varname);
}
}
}
@ -720,7 +720,7 @@ void CheckOther::CheckCharVariable()
std::string temp = "%var% [ " + tok->str() + " ]";
if ((tok2->str() != ".") && Token::Match(tok2->next(), temp.c_str()))
{
_errorLogger->reportErr(ErrorMessage::charArrayIndex(_tokenizer, tok2->next()));
ErrorMessage::charArrayIndex(_errorLogger, _tokenizer, tok2->next());
break;
}
@ -728,7 +728,7 @@ void CheckOther::CheckCharVariable()
std::string tempSecond = tok->str() + " [&|]";
if (Token::Match(tok2, tempFirst.c_str()) || Token::Match(tok2, tempSecond.c_str()))
{
_errorLogger->reportErr(ErrorMessage::charBitOp(_tokenizer, tok2));
ErrorMessage::charBitOp(_errorLogger, _tokenizer, tok2);
break;
}
}
@ -762,12 +762,12 @@ void CheckOther::CheckIncompleteStatement()
if ((tok->str() != "#") && Token::Match(tok->next(), "; %str%") && !Token::Match(tok->tokAt(3), ","))
{
_errorLogger->reportErr(ErrorMessage::constStatement(_tokenizer, tok->next(), "string"));
ErrorMessage::constStatement(_errorLogger, _tokenizer, tok->next(), "string");
}
if (!Token::Match(tok, "#") && Token::Match(tok->next(), "; %num%") && !Token::Match(tok->tokAt(3), ","))
{
_errorLogger->reportErr(ErrorMessage::constStatement(_tokenizer, tok->next(), "numeric"));
ErrorMessage::constStatement(_errorLogger, _tokenizer, tok->next(), "numeric");
}
}
}
@ -802,12 +802,12 @@ void CheckOther::strPlusChar()
// char constant..
const char *s = tok->strAt(3);
if (*s == '\'')
_errorLogger->reportErr(ErrorMessage::strPlusChar(_tokenizer, tok->next()));
ErrorMessage::strPlusChar(_errorLogger, _tokenizer, tok->next());
// char variable..
unsigned int varid = tok->tokAt(3)->varId();
if (varid > 0 && varid < 10000 && charVars[varid])
_errorLogger->reportErr(ErrorMessage::strPlusChar(_tokenizer, tok->next()));
ErrorMessage::strPlusChar(_errorLogger, _tokenizer, tok->next());
}
}
}

View File

@ -18,12 +18,27 @@
*/
#include "errormessage.h"
#include "errorlogger.h"
#include "tokenize.h"
#include "token.h"
std::string ErrorMessage::msg1(const Tokenizer *tokenizer, const Token *Location)
#include <sstream>
void ErrorMessage::_writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg)
{
return tokenizer->fileLine(Location) + ": ";
logger->reportErr(tokenizer->fileLine(tok) + ": (" + severity + ") " + msg);
}
void ErrorMessage::_writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg)
{
std::ostringstream ostr;
for (std::list<const Token *>::const_iterator tok = callstack.begin(); tok != callstack.end(); ++tok)
ostr << (tok == callstack.begin() ? "" : " -> ") << tokenizer->fileLine(*tok);
logger->reportErr(ostr.str() + ": (" + severity + ") " + msg);
}
void ErrorMessage::_writemsg(ErrorLogger *logger, const std::string msg)
{
logger->reportErr(msg);
}

View File

@ -21,307 +21,311 @@
#ifndef errormessageH
#define errormessageH
#include <list>
#include <string>
#include "settings.h"
class ErrorLogger;
class Token;
class Tokenizer;
class ErrorMessage
{
private:
ErrorMessage() { }
static std::string msg1(const Tokenizer *tokenizer, const Token *Location);
static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg);
static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg);
static void _writemsg(ErrorLogger *logger, const std::string msg);
public:
static std::string arrayIndexOutOfBounds(const Tokenizer *tokenizer, const Token *Location)
static void arrayIndexOutOfBounds(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &Location)
{
return msg1(tokenizer, Location) + std::string("(all) ") + "Array index out of bounds";
_writemsg(logger, tokenizer, Location, "all", "Array index out of bounds");
}
static bool arrayIndexOutOfBounds(const Settings &s)
{
return s._showAll;
}
static std::string bufferOverrun(const Tokenizer *tokenizer, const Token *Location)
static void bufferOverrun(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(all) ") + "Buffer overrun";
_writemsg(logger, tokenizer, Location, "all", "Buffer overrun");
}
static bool bufferOverrun(const Settings &s)
{
return s._showAll;
}
static std::string outOfBounds(const Tokenizer *tokenizer, const Token *Location, const std::string &what)
static void outOfBounds(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &what)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "" + what + " is out of bounds";
_writemsg(logger, tokenizer, Location, "always", "" + what + " is out of bounds");
}
static bool outOfBounds()
{
return true;
}
static std::string noConstructor(const Tokenizer *tokenizer, const Token *Location, const std::string &classname)
static void noConstructor(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &classname)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "The class '" + classname + "' has no constructor";
_writemsg(logger, tokenizer, Location, "style", "The class '" + classname + "' has no constructor");
}
static bool noConstructor(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string uninitVar(const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &varname)
static void uninitVar(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Uninitialized member variable '" + classname + "::" + varname + "'";
_writemsg(logger, tokenizer, Location, "always", "Uninitialized member variable '" + classname + "::" + varname + "'");
}
static bool uninitVar()
{
return true;
}
static std::string unusedPrivateFunction(const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &funcname)
static void unusedPrivateFunction(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &classname, const std::string &funcname)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Unused private function '" + classname + "::" + funcname + "'";
_writemsg(logger, tokenizer, Location, "style", "Unused private function '" + classname + "::" + funcname + "'");
}
static bool unusedPrivateFunction(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string memsetClass(const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc)
static void memsetClass(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Using '" + memfunc + "' on class";
_writemsg(logger, tokenizer, Location, "always", "Using '" + memfunc + "' on class");
}
static bool memsetClass()
{
return true;
}
static std::string memsetStruct(const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc, const std::string &classname)
static void memsetStruct(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &memfunc, const std::string &classname)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Using '" + memfunc + "' on struct that contains a 'std::" + classname + "'";
_writemsg(logger, tokenizer, Location, "always", "Using '" + memfunc + "' on struct that contains a 'std::" + classname + "'");
}
static bool memsetStruct()
{
return true;
}
static std::string operatorEq(const Tokenizer *tokenizer, const Token *Location)
static void operatorEq(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "'operator=' should return something";
_writemsg(logger, tokenizer, Location, "style", "'operator=' should return something");
}
static bool operatorEq(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string virtualDestructor(const Tokenizer *tokenizer, const Token *Location, const std::string &Base, const std::string &Derived)
static void virtualDestructor(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &Base, const std::string &Derived)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Class " + Base + " which is inherited by class " + Derived + " does not have a virtual destructor";
_writemsg(logger, tokenizer, Location, "always", "Class " + Base + " which is inherited by class " + Derived + " does not have a virtual destructor");
}
static bool virtualDestructor()
{
return true;
}
static std::string unusedFunction(const std::string &filename, const std::string &funcname)
static void unusedFunction(ErrorLogger *logger, const std::string &filename, const std::string &funcname)
{
return std::string("(all style) ") + "[" + filename + "]: The function '" + funcname + "' is never used";
_writemsg(logger, "[" + filename + "]: The function '" + funcname + "' is never used");
}
static bool unusedFunction(const Settings &s)
{
return s._checkCodingStyle || s._showAll;
}
static std::string mismatchAllocDealloc(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
static void mismatchAllocDealloc(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(all) ") + "Mismatching allocation and deallocation: " + varname + "";
_writemsg(logger, tokenizer, Location, "all", "Mismatching allocation and deallocation: " + varname + "");
}
static bool mismatchAllocDealloc(const Settings &s)
{
return s._showAll;
}
static std::string memleak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
static void memleak(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Memory leak: " + varname + "";
_writemsg(logger, tokenizer, Location, "always", "Memory leak: " + varname + "");
}
static bool memleak()
{
return true;
}
static std::string memleakall(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
static void memleakall(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(all) ") + "Memory leak: " + varname + "";
_writemsg(logger, tokenizer, Location, "all", "Memory leak: " + varname + "");
}
static bool memleakall(const Settings &s)
{
return s._showAll;
}
static std::string resourceLeak(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
static void resourceLeak(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Resource leak: " + varname + "";
_writemsg(logger, tokenizer, Location, "always", "Resource leak: " + varname + "");
}
static bool resourceLeak()
{
return true;
}
static std::string deallocDealloc(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
static void deallocDealloc(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Deallocating a deallocated pointer: " + varname + "";
_writemsg(logger, tokenizer, Location, "always", "Deallocating a deallocated pointer: " + varname + "");
}
static bool deallocDealloc()
{
return true;
}
static std::string deallocuse(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
static void deallocuse(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Using '" + varname + "' after it is deallocated / released";
_writemsg(logger, tokenizer, Location, "always", "Using '" + varname + "' after it is deallocated / released");
}
static bool deallocuse()
{
return true;
}
static std::string cstyleCast(const Tokenizer *tokenizer, const Token *Location)
static void cstyleCast(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "C-style pointer casting";
_writemsg(logger, tokenizer, Location, "style", "C-style pointer casting");
}
static bool cstyleCast(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string redundantIfDelete0(const Tokenizer *tokenizer, const Token *Location)
static void redundantIfDelete0(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Redundant condition. It is safe to deallocate a NULL pointer";
_writemsg(logger, tokenizer, Location, "style", "Redundant condition. It is safe to deallocate a NULL pointer");
}
static bool redundantIfDelete0(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string redundantIfRemove(const Tokenizer *tokenizer, const Token *Location)
static void redundantIfRemove(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Redundant condition. The remove function in the STL will not do anything if element doesn't exist";
_writemsg(logger, tokenizer, Location, "style", "Redundant condition. The remove function in the STL will not do anything if element doesn't exist");
}
static bool redundantIfRemove(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string dangerousUsageStrtol(const Tokenizer *tokenizer, const Token *Location)
static void dangerousUsageStrtol(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36";
_writemsg(logger, tokenizer, Location, "always", "Invalid radix in call to strtol or strtoul. Must be 0 or 2-36");
}
static bool dangerousUsageStrtol()
{
return true;
}
static std::string ifNoAction(const Tokenizer *tokenizer, const Token *Location)
static void ifNoAction(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Found redundant if condition - 'if (condition);'";
_writemsg(logger, tokenizer, Location, "style", "Found redundant if condition - 'if (condition);'");
}
static bool ifNoAction(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string sprintfOverlappingData(const Tokenizer *tokenizer, const Token *Location, const Settings &settings, const std::string &varname)
static void sprintfOverlappingData(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Overlapping data buffer " + varname + "" + std::string(settings._verbose ? "\n -- If copying takes place between objects that overlap as a result of a\n call to sprintf() or snprintf(), the results are undefined.\n http://www.opengroup.org/onlinepubs/000095399/functions/printf.html" : "");
_writemsg(logger, tokenizer, Location, "always", "Overlapping data buffer " + varname + "");
}
static bool sprintfOverlappingData()
{
return true;
}
static std::string udivError(const Tokenizer *tokenizer, const Token *Location)
static void udivError(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Unsigned division. The result will be wrong.";
_writemsg(logger, tokenizer, Location, "always", "Unsigned division. The result will be wrong.");
}
static bool udivError()
{
return true;
}
static std::string udivWarning(const Tokenizer *tokenizer, const Token *Location)
static void udivWarning(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(all style) ") + "Warning: Division with signed and unsigned operators";
_writemsg(logger, tokenizer, Location, "all style", "Warning: Division with signed and unsigned operators");
}
static bool udivWarning(const Settings &s)
{
return s._checkCodingStyle || s._showAll;
}
static std::string unusedStructMember(const Tokenizer *tokenizer, const Token *Location, const std::string &structname, const std::string &varname)
static void unusedStructMember(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &structname, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "struct or union member '" + structname + "::" + varname + "' is never used";
_writemsg(logger, tokenizer, Location, "style", "struct or union member '" + structname + "::" + varname + "' is never used");
}
static bool unusedStructMember(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string passedByValue(const Tokenizer *tokenizer, const Token *Location, const std::string &parname)
static void passedByValue(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &parname)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Function parameter '" + parname + "' is passed by value. It could be passed by reference instead.";
_writemsg(logger, tokenizer, Location, "style", "Function parameter '" + parname + "' is passed by value. It could be passed by reference instead.");
}
static bool passedByValue(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string constStatement(const Tokenizer *tokenizer, const Token *Location, const std::string &type)
static void constStatement(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &type)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Redundant code: Found a statement that begins with " + type + " constant";
_writemsg(logger, tokenizer, Location, "style", "Redundant code: Found a statement that begins with " + type + " constant");
}
static bool constStatement(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string charArrayIndex(const Tokenizer *tokenizer, const Token *Location)
static void charArrayIndex(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Warning - using char variable as array index";
_writemsg(logger, tokenizer, Location, "style", "Warning - using char variable as array index");
}
static bool charArrayIndex(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string charBitOp(const Tokenizer *tokenizer, const Token *Location)
static void charBitOp(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Warning - using char variable in bit operation";
_writemsg(logger, tokenizer, Location, "style", "Warning - using char variable in bit operation");
}
static bool charBitOp(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string variableScope(const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
static void variableScope(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &varname)
{
return msg1(tokenizer, Location) + std::string("(never) ") + "The scope of the variable " + varname + " can be limited";
_writemsg(logger, tokenizer, Location, "never", "The scope of the variable " + varname + " can be limited");
}
static bool variableScope()
{
return false;
}
static std::string conditionAlwaysTrueFalse(const Tokenizer *tokenizer, const Token *Location, const std::string &truefalse)
static void conditionAlwaysTrueFalse(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location, const std::string &truefalse)
{
return msg1(tokenizer, Location) + std::string("(style) ") + "Condition is always " + truefalse + "";
_writemsg(logger, tokenizer, Location, "style", "Condition is always " + truefalse + "");
}
static bool conditionAlwaysTrueFalse(const Settings &s)
{
return s._checkCodingStyle;
}
static std::string strPlusChar(const Tokenizer *tokenizer, const Token *Location)
static void strPlusChar(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *Location)
{
return msg1(tokenizer, Location) + std::string("(always) ") + "Unusual pointer arithmetic";
_writemsg(logger, tokenizer, Location, "always", "Unusual pointer arithmetic");
}
static bool strPlusChar()
{

View File

@ -128,15 +128,19 @@ int main()
fout << "// THIS FILE IS GENERATED BY MACHINE, SEE ../tools/errmsg.cpp !\n\n";
fout << "#ifndef errormessageH\n";
fout << "#define errormessageH\n";
fout << "#include <list>\n";
fout << "#include <string>\n";
fout << "#include \"settings.h\"\n";
fout << "class ErrorLogger;\n";
fout << "class Token;\n";
fout << "class Tokenizer;\n";
fout << "class ErrorMessage\n";
fout << "{\n";
fout << "private:\n";
fout << " ErrorMessage() { }\n";
fout << " static std::string msg1(const Tokenizer *tokenizer, const Token *Location);\n";
fout << " static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const Token *tok, const char severity[], const std::string msg);\n";
fout << " static void _writemsg(ErrorLogger *logger, const Tokenizer *tokenizer, const std::list<const Token *> &callstack, const char severity[], const std::string msg);\n";
fout << " static void _writemsg(ErrorLogger *logger, const std::string msg);\n";
fout << "public:\n";
for (std::list<Message>::const_iterator it = err.begin(); it != err.end(); ++it)
it->generateCode(fout);
@ -218,17 +222,32 @@ void Message::generateCode(std::ostream &ostr) const
bool loc = bool(_msg.substr(0, 4) != "[%1]");
// Error message..
ostr << " static std::string " << _funcname << "(";
ostr << " static void " << _funcname << "(ErrorLogger *logger, ";
if (loc)
ostr << "const Tokenizer *tokenizer, const Token *Location";
{
ostr << "const Tokenizer *tokenizer, ";
if (_funcname == "mismatchAllocDealloc" ||
_funcname == "arrayIndexOutOfBounds")
ostr << "const std::list<const Token *> &Location";
else
ostr << "const Token *Location";
}
/*
if (_details.size())
ostr << ", const Settings &settings";
*/
if (! _par1.empty())
ostr << (loc ? ", " : "") << "const std::string &" << _par1;
if (! _par2.empty())
ostr << ", const std::string &" << _par2;
ostr << ")\n";
ostr << " {\n";
ostr << " _writemsg(logger, ";
if (loc)
ostr << "tokenizer, Location, \"" << stringifySettings(true) << "\", ";
ostr << msg(true) << ");\n";
/*
ostr << " return ";
if (loc)
ostr << "msg1(tokenizer, Location) + ";
@ -248,6 +267,7 @@ void Message::generateCode(std::ostream &ostr) const
}
ostr << "\" : \"\");\n";
}
*/
ostr << " }\n";
// Settings..