diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index 423ad1e77..06bad51ff 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -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_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"); } diff --git a/src/checkbufferoverrun.h b/src/checkbufferoverrun.h index 7037d8955..e652e5cfd 100644 --- a/src/checkbufferoverrun.h +++ b/src/checkbufferoverrun.h @@ -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 _callStack; + + void arrayIndexOutOfBounds(const Token *tok); }; //--------------------------------------------------------------------------- diff --git a/src/checkclass.cpp b/src/checkclass.cpp index 983439613..eac6627f6 100644 --- a/src/checkclass.cpp +++ b/src/checkclass.cpp @@ -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()); } } } diff --git a/src/checkfunctionusage.cpp b/src/checkfunctionusage.cpp index 7e7515493..58edf77d8 100644 --- a/src/checkfunctionusage.cpp +++ b/src/checkfunctionusage.cpp @@ -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) { diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index 64dc72195..a74d1655d 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -291,27 +291,15 @@ const char * CheckMemoryLeakClass::call_func(const Token *tok, std::list &callstack, const char varname[]) -{ - if (! ErrorMessage::mismatchAllocDealloc(_settings)) - return; - std::ostringstream errmsg; - for (std::list::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 { 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 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 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 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; } diff --git a/src/checkother.cpp b/src/checkother.cpp index 2ece51ead..598e347b9 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -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()); } } } diff --git a/src/errormessage.cpp b/src/errormessage.cpp index cde24da55..cec9b72d0 100644 --- a/src/errormessage.cpp +++ b/src/errormessage.cpp @@ -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 + +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 &callstack, const char severity[], const std::string msg) +{ + std::ostringstream ostr; + for (std::list::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); +} diff --git a/src/errormessage.h b/src/errormessage.h index e3866cf92..8f9c55fe5 100644 --- a/src/errormessage.h +++ b/src/errormessage.h @@ -21,307 +21,311 @@ #ifndef errormessageH #define errormessageH +#include #include #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 &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 &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 &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() { diff --git a/tools/errmsg.cpp b/tools/errmsg.cpp index 1ed42907c..9554c28d3 100644 --- a/tools/errmsg.cpp +++ b/tools/errmsg.cpp @@ -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 \n"; fout << "#include \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 &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::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 &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..