From 38e7209d26f863e4992f66929c7036dc47a9fa9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 29 Dec 2010 12:43:29 +0100 Subject: [PATCH] Fixed #2373 (Using XML2 in --errorlist output) --- cli/cmdlineparser.cpp | 1 + cli/cppcheckexecutor.cpp | 2 +- lib/check.h | 2 +- lib/checkautovariables.h | 15 +++---- lib/checkbufferoverrun.h | 21 +++++----- lib/checkclass.h | 27 ++++++------ lib/checkexceptionsafety.h | 7 ++-- lib/checkmemoryleak.h | 29 +++++++------ lib/checknullpointer.h | 5 ++- lib/checkobsoletefunctions.h | 6 ++- lib/checkother.h | 58 +++++++++++++------------- lib/checkpostfixoperator.h | 5 ++- lib/checkstl.h | 31 +++++++------- lib/checkuninitvar.h | 10 +++-- lib/checkunusedfunctions.h | 5 ++- lib/cppcheck.cpp | 10 ++--- lib/preprocessor.cpp | 79 +++++++++++++++++++++++------------- lib/preprocessor.h | 6 ++- lib/tokenize.cpp | 7 ++-- lib/tokenize.h | 2 +- test/testbufferoverrun.cpp | 2 +- 21 files changed, 187 insertions(+), 143 deletions(-) diff --git a/cli/cmdlineparser.cpp b/cli/cmdlineparser.cpp index 4fe8211b3..f45bd7408 100644 --- a/cli/cmdlineparser.cpp +++ b/cli/cmdlineparser.cpp @@ -347,6 +347,7 @@ bool CmdLineParser::ParseFromArgs(int argc, const char* const argv[]) { //_cppcheck->getErrorMessages(); _showErrorMessages = true; + _settings->_xml = true; return true; } diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 50905607d..ac33e8ecf 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -52,7 +52,7 @@ bool CppCheckExecutor::parseFromArgs(CppCheck *cppcheck, int argc, const char* c if (parser.GetShowErrorMessages()) { cppcheck->getErrorMessages(); - return true; + std::exit(0); } } diff --git a/lib/check.h b/lib/check.h index 22fb5b009..45bf07bf8 100644 --- a/lib/check.h +++ b/lib/check.h @@ -95,7 +95,7 @@ public: virtual void runSimplifiedChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) = 0; /** get error messages */ - virtual void getErrorMessages() = 0; + virtual void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) = 0; /** class name, used to generate documentation */ virtual std::string name() const = 0; diff --git a/lib/checkautovariables.h b/lib/checkautovariables.h index 3f1cdcef7..974659989 100644 --- a/lib/checkautovariables.h +++ b/lib/checkautovariables.h @@ -87,14 +87,15 @@ private: void errorReturnAutocstr(const Token *tok); void errorReturnTempPointer(const Token *tok); - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - errorAutoVariableAssignment(0); - errorReturnPointerToLocalArray(0); - errorReturnReference(0); - errorReturnTempReference(0); - errorReturnAutocstr(0); - errorReturnTempPointer(0); + CheckAutoVariables c(0,settings,errorLogger); + c.errorAutoVariableAssignment(0); + c.errorReturnPointerToLocalArray(0); + c.errorReturnReference(0); + c.errorReturnTempReference(0); + c.errorReturnAutocstr(0); + c.errorReturnTempPointer(0); } std::string name() const diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index 942afbe69..91681a022 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -188,17 +188,18 @@ public: void cmdLineArgsError(const Token *tok); void pointerOutOfBounds(const Token *tok); // UB when result of calculation is out of bounds - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - arrayIndexOutOfBounds(0, 2, 2); - bufferOverrun(0, std::string("buffer")); - strncatUsage(0); - outOfBounds(0, "index"); - sizeArgumentAsChar(0); - terminateStrncpyError(0); - negativeIndexError(0, -1); - cmdLineArgsError(0); - pointerOutOfBounds(0); + CheckBufferOverrun c(0, settings, errorLogger); + c.arrayIndexOutOfBounds(0, 2, 2); + c.bufferOverrun(0, std::string("buffer")); + c.strncatUsage(0); + c.outOfBounds(0, "index"); + c.sizeArgumentAsChar(0); + c.terminateStrncpyError(0); + c.negativeIndexError(0, -1); + c.cmdLineArgsError(0); + c.pointerOutOfBounds(0); } std::string name() const diff --git a/lib/checkclass.h b/lib/checkclass.h index 06178893d..5ec791224 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -127,20 +127,21 @@ private: void checkConstError(const Token *tok, const std::string &classname, const std::string &funcname); void checkConstError2(const Token *tok1, const Token *tok2, const std::string &classname, const std::string &funcname); - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - noConstructorError(0, "classname", false); - uninitVarError(0, "classname", "varname"); - operatorEqVarError(0, "classname", ""); - unusedPrivateFunctionError(0, "classname", "funcname"); - memsetClassError(0, "memfunc"); - memsetStructError(0, "memfunc", "classname"); - operatorEqReturnError(0); - //virtualDestructorError(0, "Base", "Derived"); - thisSubtractionError(0); - operatorEqRetRefThisError(0); - operatorEqToSelfError(0); - checkConstError(0, "class", "function"); + CheckClass c(0, settings, errorLogger); + c.noConstructorError(0, "classname", false); + c.uninitVarError(0, "classname", "varname"); + c.operatorEqVarError(0, "classname", ""); + c.unusedPrivateFunctionError(0, "classname", "funcname"); + c.memsetClassError(0, "memfunc"); + c.memsetStructError(0, "memfunc", "classname"); + c.operatorEqReturnError(0); + //c.virtualDestructorError(0, "Base", "Derived"); + c.thisSubtractionError(0); + c.operatorEqRetRefThisError(0); + c.operatorEqToSelfError(0); + c.checkConstError(0, "class", "function"); } std::string name() const diff --git a/lib/checkexceptionsafety.h b/lib/checkexceptionsafety.h index 933393998..82e16b9ba 100644 --- a/lib/checkexceptionsafety.h +++ b/lib/checkexceptionsafety.h @@ -78,10 +78,11 @@ private: } /** Generate all possible errors (for --errorlist) */ - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - destructorsError(0); - deallocThrowError(0, "p"); + CheckExceptionSafety c(0, settings, errorLogger); + c.destructorsError(0); + c.deallocThrowError(0, "p"); } /** Short description of class (for --doc) */ diff --git a/lib/checkmemoryleak.h b/lib/checkmemoryleak.h index 2281b934f..109b40316 100644 --- a/lib/checkmemoryleak.h +++ b/lib/checkmemoryleak.h @@ -180,7 +180,10 @@ public: : Check(tokenizr, settings, errLog), CheckMemoryLeak(tokenizr, errLog) { // get the symbol database - symbolDatabase = tokenizr->getSymbolDatabase(); + if (tokenizr) + symbolDatabase = tokenizr->getSymbolDatabase(); + else + symbolDatabase = 0; } /** @brief run all simplified checks */ @@ -307,17 +310,19 @@ public: void checkScope(const Token *Tok1, const std::string &varname, unsigned int varid, bool classmember, unsigned int sz); /** Report all possible errors (for the --errorlist) */ - void getErrorMessages() + void getErrorMessages(ErrorLogger *e, const Settings *settings) { - memleakError(0, "varname"); - resourceLeakError(0, "varname"); + CheckMemoryLeakInFunction c(0, settings, e); - deallocDeallocError(0, "varname"); - deallocuseError(0, "varname"); - mismatchSizeError(0, "sz"); + c.memleakError(0, "varname"); + c.resourceLeakError(0, "varname"); + + c.deallocDeallocError(0, "varname"); + c.deallocuseError(0, "varname"); + c.mismatchSizeError(0, "sz"); std::list callstack; - mismatchAllocDealloc(callstack, "varname"); - memleakUponReallocFailureError(0, "varname"); + c.mismatchAllocDealloc(callstack, "varname"); + c.memleakUponReallocFailureError(0, "varname"); } /** @@ -385,7 +390,7 @@ private: void checkPublicFunctions(const SymbolDatabase::SpaceInfo *spaceinfo, const Token *classtok); void publicAllocationError(const Token *tok, const std::string &varname); - void getErrorMessages() + void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) { } std::string name() const @@ -423,7 +428,7 @@ public: private: - void getErrorMessages() + void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) { } std::string name() const @@ -463,7 +468,7 @@ private: void functionCallLeak(const Token *loc, const std::string &alloc, const std::string &functionCall); - void getErrorMessages() + void getErrorMessages(ErrorLogger * /*errorLogger*/, const Settings * /*settings*/) { } std::string name() const diff --git a/lib/checknullpointer.h b/lib/checknullpointer.h index bbc0a79c2..848ec4a6c 100644 --- a/lib/checknullpointer.h +++ b/lib/checknullpointer.h @@ -101,9 +101,10 @@ public: void nullPointerError(const Token *tok, const std::string &varname); void nullPointerError(const Token *tok, const std::string &varname, const unsigned int line); - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - nullPointerError(0, "pointer"); + CheckNullPointer c(0, settings, errorLogger); + c.nullPointerError(0, "pointer"); } std::string name() const diff --git a/lib/checkobsoletefunctions.h b/lib/checkobsoletefunctions.h index ff93793c3..d9e7f6bb9 100644 --- a/lib/checkobsoletefunctions.h +++ b/lib/checkobsoletefunctions.h @@ -112,12 +112,14 @@ private: } - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { + CheckObsoleteFunctions c(0, settings, errorLogger); + std::list< std::pair >::const_iterator it(_obsoleteFunctions.begin()), itend(_obsoleteFunctions.end()); for (; it!=itend; ++it) { - reportError(0, Severity::style, "obsoleteFunctions"+it->first, it->second); + c.reportError(0, Severity::style, "obsoleteFunctions"+it->first, it->second); } } diff --git a/lib/checkother.h b/lib/checkother.h index bc4af9f10..1117fee42 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -184,38 +184,40 @@ public: void incorrectLogicOperatorError(const Token *tok); void misusedScopeObjectError(const Token *tok, const std::string &varname); - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { + CheckOther c(0, settings, errorLogger); + // error - sprintfOverlappingDataError(0, "varname"); - udivError(0); - zerodivError(0); - mathfunctionCallError(0); - fflushOnInputStreamError(0, "stdin"); - misusedScopeObjectError(NULL, "varname"); + c.sprintfOverlappingDataError(0, "varname"); + c.udivError(0); + c.zerodivError(0); + c.mathfunctionCallError(0); + c.fflushOnInputStreamError(0, "stdin"); + c.misusedScopeObjectError(NULL, "varname"); // style/warning - cstyleCastError(0); - dangerousUsageStrtolError(0); - unusedStructMemberError(0, "structname", "variable"); - passedByValueError(0, "parametername"); - constStatementError(0, "type"); - charArrayIndexError(0); - charBitOpError(0); - variableScopeError(0, "varname"); - conditionAlwaysTrueFalse(0, "true/false"); - strPlusChar(0); - sizeofsizeofError(0); - sizeofCalculationError(0); - redundantAssignmentInSwitchError(0, "varname"); - selfAssignmentError(0, "varname"); - assignmentInAssertError(0, "varname"); - invalidScanfError(0); - incorrectLogicOperatorError(0); - unusedVariableError(0, "varname"); - allocatedButUnusedVariableError(0, "varname"); - unreadVariableError(0, "varname"); - unassignedVariableError(0, "varname"); + c.cstyleCastError(0); + c.dangerousUsageStrtolError(0); + c.unusedStructMemberError(0, "structname", "variable"); + c.passedByValueError(0, "parametername"); + c.constStatementError(0, "type"); + c.charArrayIndexError(0); + c.charBitOpError(0); + c.variableScopeError(0, "varname"); + c.conditionAlwaysTrueFalse(0, "true/false"); + c.strPlusChar(0); + c.sizeofsizeofError(0); + c.sizeofCalculationError(0); + c.redundantAssignmentInSwitchError(0, "varname"); + c.selfAssignmentError(0, "varname"); + c.assignmentInAssertError(0, "varname"); + c.invalidScanfError(0); + c.incorrectLogicOperatorError(0); + c.unusedVariableError(0, "varname"); + c.allocatedButUnusedVariableError(0, "varname"); + c.unreadVariableError(0, "varname"); + c.unassignedVariableError(0, "varname"); } std::string name() const diff --git a/lib/checkpostfixoperator.h b/lib/checkpostfixoperator.h index b557edb77..eee5ad021 100644 --- a/lib/checkpostfixoperator.h +++ b/lib/checkpostfixoperator.h @@ -56,9 +56,10 @@ private: /** Report Error */ void postfixOperatorError(const Token *tok); - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - postfixOperatorError(0); + CheckPostfixOperator c(0, settings, errorLogger); + c.postfixOperatorError(0); } std::string name() const diff --git a/lib/checkstl.h b/lib/checkstl.h index 0d64b5641..896dfbdda 100644 --- a/lib/checkstl.h +++ b/lib/checkstl.h @@ -154,22 +154,23 @@ private: void sizeError(const Token *tok); void redundantIfRemoveError(const Token *tok); - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - invalidIteratorError(0, "iterator"); - iteratorsError(0, "container1", "container2"); - mismatchingContainersError(0); - dereferenceErasedError(0, "iter"); - stlOutOfBoundsError(0, "i", "foo"); - eraseError(0); - invalidIteratorError(0, "push_back|push_front|insert", "iterator"); - invalidPointerError(0, "pointer"); - stlBoundriesError(0, "container"); - if_findError(0, false); - if_findError(0, true); - string_c_strError(0); - sizeError(0); - redundantIfRemoveError(0); + CheckStl c(0, settings, errorLogger); + c.invalidIteratorError(0, "iterator"); + c.iteratorsError(0, "container1", "container2"); + c.mismatchingContainersError(0); + c.dereferenceErasedError(0, "iter"); + c.stlOutOfBoundsError(0, "i", "foo"); + c.eraseError(0); + c.invalidIteratorError(0, "push_back|push_front|insert", "iterator"); + c.invalidPointerError(0, "pointer"); + c.stlBoundriesError(0, "container"); + c.if_findError(0, false); + c.if_findError(0, true); + c.string_c_strError(0); + c.sizeError(0); + c.redundantIfRemoveError(0); } std::string name() const diff --git a/lib/checkuninitvar.h b/lib/checkuninitvar.h index 58f4c4ddb..dd643c75c 100644 --- a/lib/checkuninitvar.h +++ b/lib/checkuninitvar.h @@ -77,12 +77,14 @@ public: void uninitdataError(const Token *tok, const std::string &varname); void uninitvarError(const Token *tok, const std::string &varname); - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { + CheckUninitVar c(0, settings, errorLogger); + // error - uninitstringError(0, "varname"); - uninitdataError(0, "varname"); - uninitvarError(0, "varname"); + c.uninitstringError(0, "varname"); + c.uninitdataError(0, "varname"); + c.uninitvarError(0, "varname"); } std::string name() const diff --git a/lib/checkunusedfunctions.h b/lib/checkunusedfunctions.h index 54cfc5e5d..d64fa7944 100644 --- a/lib/checkunusedfunctions.h +++ b/lib/checkunusedfunctions.h @@ -50,9 +50,10 @@ public: private: - void getErrorMessages() + void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - unusedFunctionError(0, "", "funcName"); + CheckUnusedFunctions c(0, settings, errorLogger); + c.unusedFunctionError(errorLogger, "", "funcName"); } /** diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 160b7560c..b0f96fe6e 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -436,16 +436,14 @@ void CppCheck::reportStatus(unsigned int /*index*/, unsigned int /*max*/) void CppCheck::getErrorMessages() { // call all "getErrorMessages" in all registered Check classes - std::cout << ErrorLogger::ErrorMessage::getXMLHeader(1); + std::cout << ErrorLogger::ErrorMessage::getXMLHeader(_settings._xml_version); for (std::list::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) - { - (*it)->getErrorMessages(); - } + (*it)->getErrorMessages(this, &_settings); Tokenizer tokenizer(&_settings, 0); - tokenizer.getErrorMessages(); + tokenizer.getErrorMessages(this, &_settings); - Preprocessor::getErrorMessages(std::cout); + Preprocessor::getErrorMessages(this, &_settings); std::cout << ErrorLogger::ErrorMessage::getXMLFooter() << std::endl; } diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 8a127446a..6def6da55 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1399,9 +1399,9 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg, { if (settings && !settings->userDefines.empty()) { - std::ostringstream errmsg; - errmsg << line; - writeError(filename, lineno, errorLogger, "preprocessorErrorDirective", errmsg.str()); + Settings settings2(*settings); + Preprocessor preprocessor(&settings2, errorLogger); + preprocessor.error(filename, lineno, line); } return ""; } @@ -1433,6 +1433,22 @@ std::string Preprocessor::getcode(const std::string &filedata, std::string cfg, return expandMacros(ret.str(), filename, errorLogger); } +void Preprocessor::error(const std::string &filename, unsigned int linenr, const std::string &msg) +{ + std::list locationList; + if (!filename.empty()) + { + ErrorLogger::ErrorMessage::FileLocation loc; + loc.line = linenr; + loc.setfile(filename); + locationList.push_back(loc); + } + _errorLogger->reportErr(ErrorLogger::ErrorMessage(locationList, + Severity::error, + msg, + "preprocessorErrorDirective")); +} + Preprocessor::HeaderTypes Preprocessor::getHeaderFileName(std::string &str) { std::string result; @@ -1606,24 +1622,36 @@ void Preprocessor::handleIncludes(std::string &code, } } - std::list locationList; - ErrorLogger::ErrorMessage::FileLocation loc; - loc.line = linenr; /** @todo set correct line */ - loc.setfile(Path::toNativeSeparators(filePath)); - locationList.push_back(loc); - - // If the missing include is a system header then this is - // currently a debug-message. - const Severity::SeverityType severity = (headerType == UserHeader) ? Severity::information : Severity::debug; - const std::string id = (headerType == UserHeader) ? "missingInclude" : "debug"; - ErrorLogger::ErrorMessage errmsg(locationList, severity, "Include file: \"" + filename + "\" not found.", id); - errmsg.file0 = file0; - _errorLogger->reportErr(errmsg); + missingInclude(Path::toNativeSeparators(filePath), + linenr, + filename, + headerType == UserHeader); } } } } +// Report that include is missing +void Preprocessor::missingInclude(const std::string &filename, unsigned int linenr, const std::string &header, bool userheader) +{ + std::list locationList; + if (!filename.empty()) + { + ErrorLogger::ErrorMessage::FileLocation loc; + loc.line = linenr; + loc.setfile(filename); + locationList.push_back(loc); + } + + // If the missing include is a system header then this is + // currently a debug-message. + const Severity::SeverityType severity = userheader ? Severity::information : Severity::debug; + const std::string id = userheader ? "missingInclude" : "debug"; + ErrorLogger::ErrorMessage errmsg(locationList, severity, "Include file: \"" + header + "\" not found.", id); + errmsg.file0 = file0; + _errorLogger->reportErr(errmsg); +} + /** * Skip string in line. A string begins and ends with either a " or a ' * @param line the string @@ -2405,18 +2433,11 @@ std::string Preprocessor::expandMacros(const std::string &code, std::string file return ostr.str(); } -void Preprocessor::getErrorMessages(std::ostream &ostr) -{ - std::list locationList; - const ErrorLogger::ErrorMessage errmsg(locationList, - Severity::style, - "Include file: \"\" not found.", - "missingInclude"); - ostr << errmsg.toXML(false, 1) << std::endl; - const ErrorLogger::ErrorMessage errmsg2(locationList, - Severity::error, - "#error ...", - "preprocessorErrorDirective"); - ostr << errmsg2.toXML(false, 1) << std::endl; +void Preprocessor::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) +{ + Settings settings2(*settings); + Preprocessor preprocessor(&settings2, errorLogger); + preprocessor.missingInclude("", 1, "", true); + preprocessor.error("", 1, "#error message"); // #error .. } diff --git a/lib/preprocessor.h b/lib/preprocessor.h index e1d849cd7..8c31568b6 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -196,9 +196,13 @@ public: */ static bool match_cfg_def(const std::map &cfg, std::string def); - static void getErrorMessages(std::ostream &ostr); + static void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings); private: + void missingInclude(const std::string &filename, unsigned int linenr, const std::string &header, bool userheader); + + void error(const std::string &filename, unsigned int linenr, const std::string &msg); + /** * Search includes from code and append code from the included * file diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 3efb06e2f..3b801f4d3 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -8224,10 +8224,11 @@ void Tokenizer::simplifyConst() } } -void Tokenizer::getErrorMessages() +void Tokenizer::getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) { - syntaxError(0, ' '); - cppcheckError(0); + Tokenizer t(settings, errorLogger); + t.syntaxError(0, ' '); + t.cppcheckError(0); } /** find pattern */ diff --git a/lib/tokenize.h b/lib/tokenize.h index 7d8953fd2..47b4e5afc 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -133,7 +133,7 @@ public: /** * get error messages */ - virtual void getErrorMessages(); + virtual void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings); /** Simplify assignment in function call "f(x=g());" => "x=g();f(x);" */ diff --git a/test/testbufferoverrun.cpp b/test/testbufferoverrun.cpp index ad192fc97..0708837cc 100644 --- a/test/testbufferoverrun.cpp +++ b/test/testbufferoverrun.cpp @@ -2763,7 +2763,7 @@ private: { // Ticket #2292: segmentation fault when using --errorlist CheckBufferOverrun c; - c.getErrorMessages(); + c.getErrorMessages(this, 0); } };