diff --git a/src/checkbufferoverrun.cpp b/src/checkbufferoverrun.cpp index 4aef4686c..50a8bccb0 100644 --- a/src/checkbufferoverrun.cpp +++ b/src/checkbufferoverrun.cpp @@ -36,6 +36,13 @@ //--------------------------------------------------------------------------- +// Register this check class (by creating a static instance of it) +namespace +{ +CheckBufferOverrunClass instance; +} + +//--------------------------------------------------------------------------- void CheckBufferOverrunClass::arrayIndexOutOfBounds(const Token *tok) { diff --git a/src/checkdangerousfunctions.cpp b/src/checkdangerousfunctions.cpp index 6779fed51..cf5940ddc 100644 --- a/src/checkdangerousfunctions.cpp +++ b/src/checkdangerousfunctions.cpp @@ -23,6 +23,9 @@ #include "checkdangerousfunctions.h" +#include "tokenize.h" +#include "token.h" + #include #include #include @@ -33,19 +36,11 @@ //--------------------------------------------------------------------------- -// _callStack used when parsing into subfunctions. - -CheckDangerousFunctionsClass::CheckDangerousFunctionsClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) - : _settings(settings) +// Register this check class (by creating a static instance of it) +namespace { - _tokenizer = tokenizer; - _errorLogger = errorLogger; -} - -CheckDangerousFunctionsClass::~CheckDangerousFunctionsClass() -{ - +CheckDangerousFunctionsClass instance; } //--------------------------------------------------------------------------- diff --git a/src/checkdangerousfunctions.h b/src/checkdangerousfunctions.h index 768b43474..e2f3b5e63 100644 --- a/src/checkdangerousfunctions.h +++ b/src/checkdangerousfunctions.h @@ -23,23 +23,26 @@ #define CheckDangerousFunctionsH //--------------------------------------------------------------------------- -#include "tokenize.h" -#include "errorlogger.h" +#include "check.h" -class CheckDangerousFunctionsClass +class CheckDangerousFunctionsClass : public Check { public: - CheckDangerousFunctionsClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger); - ~CheckDangerousFunctionsClass(); + CheckDangerousFunctionsClass() : Check() + { } + + CheckDangerousFunctionsClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : Check(tokenizer, settings, errorLogger) + { } + + void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + { + CheckDangerousFunctionsClass checkDangerousFunctionsClass(tokenizer, settings, errorLogger); + checkDangerousFunctionsClass.dangerousFunctions(); + } /** Check for buffer overruns */ void dangerousFunctions(); - -private: - - const Tokenizer *_tokenizer; - const Settings _settings; - ErrorLogger *_errorLogger; }; //--------------------------------------------------------------------------- diff --git a/src/checkmemoryleak.cpp b/src/checkmemoryleak.cpp index c0407ad49..4fb8c4469 100644 --- a/src/checkmemoryleak.cpp +++ b/src/checkmemoryleak.cpp @@ -20,6 +20,8 @@ #include "checkmemoryleak.h" +#include "tokenize.h" + #include #include #include @@ -27,17 +29,13 @@ //--------------------------------------------------------------------------- -CheckMemoryLeakClass::CheckMemoryLeakClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) - : _settings(settings) +// Register this check class (by creating a static instance of it) +namespace { - _tokenizer = tokenizer; - _errorLogger = errorLogger; +CheckMemoryLeakClass instance; } -CheckMemoryLeakClass::~CheckMemoryLeakClass() -{ - -} +//--------------------------------------------------------------------------- bool CheckMemoryLeakClass::isclass(const Token *tok) { @@ -260,7 +258,7 @@ const char * CheckMemoryLeakClass::call_func(const Token *tok, std::list_showAll ? 0 : "callfunc"; } } @@ -425,10 +423,10 @@ Token *CheckMemoryLeakClass::getcode(const Token *tok, std::list { if (isclass(tok->tokAt(3))) { - if (_settings._showAll) + if (_settings->_showAll) { - if (_settings.isAutoDealloc(tok->strAt(3))) + if (_settings->isAutoDealloc(tok->strAt(3))) { // This class has automatic deallocation alloc = No; @@ -800,7 +798,7 @@ void CheckMemoryLeakClass::simplifycode(Token *tok, bool &all) } // Two "if alloc ;" after one another.. perhaps only one of them can be executed each time - else if (!_settings._showAll && Token::Match(tok2, "[;{}] if alloc ; if alloc ;")) + else if (!_settings->_showAll && Token::Match(tok2, "[;{}] if alloc ; if alloc ;")) { erase(tok2, tok2->tokAt(4)); done = false; @@ -820,7 +818,7 @@ void CheckMemoryLeakClass::simplifycode(Token *tok, bool &all) // Otherwise, only the "if" will be deleted else if (Token::Match(tok2, "[;{}] if assign|dealloc|use ; !!else")) { - if (_settings._showAll) + if (_settings->_showAll) { erase(tok2, tok2->tokAt(3)); all = true; @@ -890,7 +888,7 @@ void CheckMemoryLeakClass::simplifycode(Token *tok, bool &all) } // Reducing if.. - else if (_settings._showAll) + else if (_settings->_showAll) { if (Token::Match(tok2, "[;{}] if { assign|dealloc|use ; return ; } !!else")) { @@ -960,7 +958,7 @@ void CheckMemoryLeakClass::simplifycode(Token *tok, bool &all) } // Remove the "if break|continue ;" that follows "dealloc ; alloc ;" - if (! _settings._showAll && Token::Match(tok2, "dealloc ; alloc ; if break|continue ;")) + if (! _settings->_showAll && Token::Match(tok2, "dealloc ; alloc ; if break|continue ;")) { tok2 = tok2->next()->next()->next(); erase(tok2, tok2->tokAt(3)); @@ -1267,7 +1265,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope(const Token *Tok1, const c MemoryLeak(result->tokAt(3), varname, alloctype, all); } - else if (_settings._showAll && (result = Token::findmatch(tok, "alloc ; ifv break|continue|return ;")) != NULL) + else if (_settings->_showAll && (result = Token::findmatch(tok, "alloc ; ifv break|continue|return ;")) != NULL) { MemoryLeak(result->tokAt(3), varname, alloctype, all); } @@ -1293,7 +1291,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope(const Token *Tok1, const c } // detect cases that "simplifycode" don't handle well.. - else if (_settings._debug) + else if (_settings->_debug) { Token *first = tok; while (first && first->str() == ";") @@ -1441,12 +1439,12 @@ void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_ParseClass(const Token * if (Token::Match(tok->next(), "%type% * %var% ;")) { // No false positives for auto deallocated classes.. - if (_settings.isAutoDealloc(tok->strAt(1))) + if (_settings->isAutoDealloc(tok->strAt(1))) continue; if (tok->isName() || Token::Match(tok, "[;}]")) { - if (_settings._showAll || !isclass(tok->tokAt(1))) + if (_settings->_showAll || !isclass(tok->tokAt(1))) CheckMemoryLeak_ClassMembers_Variable(classname.back(), tok->tokAt(3)); } } @@ -1565,7 +1563,7 @@ void CheckMemoryLeakClass::CheckMemoryLeak() CheckMemoryLeak_InFunction(); // Check that all class members are deallocated.. - if (_settings._showAll) + if (_settings->_showAll) CheckMemoryLeak_ClassMembers(); } //--------------------------------------------------------------------------- diff --git a/src/checkmemoryleak.h b/src/checkmemoryleak.h index 4df740dda..b101890ae 100644 --- a/src/checkmemoryleak.h +++ b/src/checkmemoryleak.h @@ -26,17 +26,31 @@ /** \brief Check for memory leaks */ -#include "tokenize.h" -#include "settings.h" -#include "errorlogger.h" +#include "check.h" + #include +#include #include -class CheckMemoryLeakClass +class Token; + +class CheckMemoryLeakClass : public Check { public: - CheckMemoryLeakClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger); - ~CheckMemoryLeakClass(); + CheckMemoryLeakClass() : Check() + { } + + CheckMemoryLeakClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : Check(tokenizer, settings, errorLogger) + { } + + void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + { + CheckMemoryLeakClass checkMemoryLeakClass(tokenizer, settings, errorLogger); + checkMemoryLeakClass.CheckMemoryLeak(); + } + + void CheckMemoryLeak(); private: @@ -109,9 +123,6 @@ private: AllocType GetReallocationType(const Token *tok2); bool isclass(const Token *typestr); - const Tokenizer *_tokenizer; - ErrorLogger *_errorLogger; - const Settings _settings; std::list _listAllocFunc; // Experimental functionality.. diff --git a/src/checkother.cpp b/src/checkother.cpp index 3c334e30e..d52dd9f3e 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -20,6 +20,8 @@ //--------------------------------------------------------------------------- #include "checkother.h" +#include "tokenize.h" + #include #include #include @@ -29,24 +31,15 @@ #include //--------------------------------------------------------------------------- - - - -//--------------------------------------------------------------------------- -// Warning on C-Style casts.. p = (kalle *)foo; -//--------------------------------------------------------------------------- - -CheckOther::CheckOther(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) - : _settings(settings) +// Register this check class (by creating a static instance of it) +namespace { - _tokenizer = tokenizer; - _errorLogger = errorLogger; +CheckOther instance; } -CheckOther::~CheckOther() -{ +//--------------------------------------------------------------------------- + -} void CheckOther::WarningOldStylePointerCast() { @@ -195,7 +188,7 @@ void CheckOther::redundantCondition2() void CheckOther::WarningIf() { - if (ErrorLogger::ifNoAction(_settings)) + if (ErrorLogger::ifNoAction(*_settings)) { // Search for 'if (condition);' for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) @@ -225,7 +218,7 @@ void CheckOther::WarningIf() } } - if (ErrorLogger::conditionAlwaysTrueFalse(_settings)) + if (ErrorLogger::conditionAlwaysTrueFalse(*_settings)) { // Search for 'a=b; if (a==b)' for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) @@ -393,7 +386,7 @@ void CheckOther::CheckUnsignedDivision() else if (!Token::Match(tok, "[).]") && Token::Match(tok->next(), "%var% / %var%")) { - if (ErrorLogger::udivWarning(_settings)) + if (ErrorLogger::udivWarning(*_settings)) { const char *varname1 = tok->strAt(1); const char *varname2 = tok->strAt(3); diff --git a/src/checkother.h b/src/checkother.h index 87b9860b7..07f0f32e9 100644 --- a/src/checkother.h +++ b/src/checkother.h @@ -23,14 +23,46 @@ #define CheckOtherH //--------------------------------------------------------------------------- -#include "tokenize.h" -#include "errorlogger.h" +#include "check.h" +#include "settings.h" -class CheckOther +class Token; + +class CheckOther : public Check { public: - CheckOther(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger); - ~CheckOther(); + CheckOther() : Check() + { } + + CheckOther(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + : Check(tokenizer, settings, errorLogger) + { } + + + // TODO: run these before simplification.. + // checkOther.CheckUnsignedDivision(); + // checkOther.CheckCharVariable(); + + + void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) + { + CheckOther checkOther(tokenizer, settings, errorLogger); + + if (settings->_checkCodingStyle) + { + checkOther.WarningOldStylePointerCast(); + checkOther.WarningRedundantCode(); + checkOther.WarningIf(); + checkOther.CheckVariableScope(); + checkOther.CheckConstantFunctionParameter(); + checkOther.CheckStructMemberUsage(); + checkOther.CheckIncompleteStatement(); + } + + checkOther.strPlusChar(); + checkOther.returnPointerToStackData(); + checkOther.InvalidFunctionUsage(); + } // Casting void WarningOldStylePointerCast(); @@ -75,10 +107,6 @@ protected: // if (haystack.find(needle) != haystack.end()) // haystack.remove(needle); void redundantCondition2(); - - const Tokenizer *_tokenizer; - ErrorLogger *_errorLogger; - const Settings &_settings; }; //--------------------------------------------------------------------------- diff --git a/src/cppcheck.cpp b/src/cppcheck.cpp index d1d84946f..e0659dd24 100644 --- a/src/cppcheck.cpp +++ b/src/cppcheck.cpp @@ -21,10 +21,6 @@ #include "preprocessor.h" // preprocessor. #include "tokenize.h" // <- Tokenizer -#include "checkmemoryleak.h" -#include "checkdangerousfunctions.h" -#include "checkheaders.h" -#include "checkother.h" #include "checkfunctionusage.h" #include "filelister.h" @@ -382,75 +378,13 @@ void CppCheck::checkFile(const std::string &code, const char FileName[]) _tokenizer.fillFunctionList(); - // Coding style checks that must be run before the simplifyTokenList - CheckOther checkOther(&_tokenizer, _settings, this); - - // Check for unsigned divisions where one operand is signed - if (ErrorLogger::udivWarning(_settings) || ErrorLogger::udivError()) - checkOther.CheckUnsignedDivision(); - - // Give warning when using char variable as array index - if (ErrorLogger::charArrayIndex(_settings) || ErrorLogger::charBitOp(_settings)) - checkOther.CheckCharVariable(); _tokenizer.simplifyTokenList(); - // Write simplified token list to a file.. - //std::cout << _tokenizer.tokens()->stringifyList(true) << std::endl; - if (_settings._unusedFunctions) _checkFunctionUsage.parseTokens(_tokenizer); - // Class for checking functions that should not be used - CheckDangerousFunctionsClass checkDangerousFunctions(&_tokenizer, _settings, this); - - // Memory leak - CheckMemoryLeakClass checkMemoryLeak(&_tokenizer, _settings, this); - if (ErrorLogger::memleak() || ErrorLogger::mismatchAllocDealloc()) - checkMemoryLeak.CheckMemoryLeak(); - - // Warning upon c-style pointer casts - if (ErrorLogger::cstyleCast(_settings)) - { - const char *ext = strrchr(FileName, '.'); - if (ext && strcmp(ext, ".cpp") == 0) - checkOther.WarningOldStylePointerCast(); - } - - // if (a) delete a; - if (ErrorLogger::redundantIfDelete0(_settings)) - checkOther.WarningRedundantCode(); - - // strtol and strtoul usage - if (ErrorLogger::dangerousUsageStrtol() || - ErrorLogger::sprintfOverlappingData()) - checkOther.InvalidFunctionUsage(); - - // if (condition); - if (ErrorLogger::ifNoAction(_settings) || ErrorLogger::conditionAlwaysTrueFalse(_settings)) - checkOther.WarningIf(); - - // Unused struct members.. - if (ErrorLogger::unusedStructMember(_settings)) - checkOther.CheckStructMemberUsage(); - - // Check if a constant function parameter is passed by value - if (ErrorLogger::passedByValue(_settings)) - checkOther.CheckConstantFunctionParameter(); - - // Variable scope (check if the scope could be limited) - if (ErrorLogger::variableScope()) - checkOther.CheckVariableScope(); - - // Check for various types of incomplete statements that could for example - // mean that an ';' has been added by accident - if (ErrorLogger::constStatement(_settings)) - checkOther.CheckIncompleteStatement(); - - // Unusual pointer arithmetic - if (ErrorLogger::strPlusChar()) - checkOther.strPlusChar(); - + // Run all checks in all registered Check classes for (std::list::iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) { (*it)->runChecks(&_tokenizer, &_settings, this); diff --git a/test/testcharvar.cpp b/test/testcharvar.cpp index f90d2a18d..cd304d1d8 100644 --- a/test/testcharvar.cpp +++ b/test/testcharvar.cpp @@ -53,7 +53,8 @@ private: errout.str(""); // Check char variable usage.. - CheckOther checkOther(&tokenizer, Settings(), this); + Settings settings; + CheckOther checkOther(&tokenizer, &settings, this); checkOther.CheckCharVariable(); } diff --git a/test/testdangerousfunctions.cpp b/test/testdangerousfunctions.cpp index 124f9bcac..f930b84d3 100644 --- a/test/testdangerousfunctions.cpp +++ b/test/testdangerousfunctions.cpp @@ -56,7 +56,7 @@ private: // Check for buffer overruns.. Settings settings; settings._showAll = true; - CheckDangerousFunctionsClass checkDangerousFunctions(&tokenizer, settings, this); + CheckDangerousFunctionsClass checkDangerousFunctions(&tokenizer, &settings, this); checkDangerousFunctions.dangerousFunctions(); } diff --git a/test/testdivision.cpp b/test/testdivision.cpp index d0d742d5f..a9d054f1b 100644 --- a/test/testdivision.cpp +++ b/test/testdivision.cpp @@ -52,7 +52,7 @@ private: settings._checkCodingStyle = true; // Check for unsigned divisions.. - CheckOther checkOther(&tokenizer, settings, this); + CheckOther checkOther(&tokenizer, &settings, this); checkOther.CheckUnsignedDivision(); } diff --git a/test/testincompletestatement.cpp b/test/testincompletestatement.cpp index d5fffe4cb..649928a8a 100644 --- a/test/testincompletestatement.cpp +++ b/test/testincompletestatement.cpp @@ -52,7 +52,7 @@ private: settings._showAll = true; // Check for unused variables.. - CheckOther checkOther(&tokenizer, settings, this); + CheckOther checkOther(&tokenizer, &settings, this); checkOther.CheckIncompleteStatement(); } diff --git a/test/testmemleak.cpp b/test/testmemleak.cpp index 1f668c1ba..e6d0309a7 100644 --- a/test/testmemleak.cpp +++ b/test/testmemleak.cpp @@ -54,7 +54,7 @@ private: settings._debug = true; settings._showAll = showAll; tokenizer.fillFunctionList(); - CheckMemoryLeakClass checkMemoryLeak(&tokenizer, settings, this); + CheckMemoryLeakClass checkMemoryLeak(&tokenizer, &settings, this); checkMemoryLeak.CheckMemoryLeak(); } @@ -1981,7 +1981,7 @@ private: settings.autoDealloc(istr); } - CheckMemoryLeakClass checkMemoryLeak(&tokenizer, settings, this); + CheckMemoryLeakClass checkMemoryLeak(&tokenizer, &settings, this); checkMemoryLeak.CheckMemoryLeak(); } diff --git a/test/testmemleakmp.cpp b/test/testmemleakmp.cpp index 9a01f4d78..9a73a0afc 100644 --- a/test/testmemleakmp.cpp +++ b/test/testmemleakmp.cpp @@ -34,7 +34,7 @@ public: class OurCheckMemoryLeakClass : public CheckMemoryLeakClass { public: - OurCheckMemoryLeakClass(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + OurCheckMemoryLeakClass(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : CheckMemoryLeakClass(tokenizer, settings, errorLogger) { } @@ -70,7 +70,7 @@ private: // Check.. Settings settings; - OurCheckMemoryLeakClass checkMemoryLeak(&tokenizer, settings, this); + OurCheckMemoryLeakClass checkMemoryLeak(&tokenizer, &settings, this); Token *tok = checkMemoryLeak.functionParameterCode(tokenizer.tokens(), 1); // Compare tokens.. diff --git a/test/testother.cpp b/test/testother.cpp index d11e76858..e7c62f81d 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -63,7 +63,8 @@ private: errout.str(""); // Check for redundant code.. - CheckOther checkOther(&tokenizer, Settings(), this); + Settings settings; + CheckOther checkOther(&tokenizer, &settings, this); checkOther.WarningRedundantCode(); } @@ -129,7 +130,8 @@ private: errout.str(""); // Check for redundant code.. - CheckOther checkOther(&tokenizer, Settings(), this); + Settings settings; + CheckOther checkOther(&tokenizer, &settings, this); checkOther.InvalidFunctionUsage(); } @@ -196,7 +198,8 @@ private: errout.str(""); // Check for redundant code.. - CheckOther checkOther(&tokenizer, Settings(), this); + Settings settings; + CheckOther checkOther(&tokenizer, &settings, this); checkOther.strPlusChar(); } @@ -246,7 +249,8 @@ private: errout.str(""); // Check for redundant code.. - CheckOther checkOther(&tokenizer, Settings(), this); + Settings settings; + CheckOther checkOther(&tokenizer, &settings, this); checkOther.returnPointerToStackData(); } diff --git a/test/testredundantif.cpp b/test/testredundantif.cpp index f110b7dcc..ee5c4e301 100644 --- a/test/testredundantif.cpp +++ b/test/testredundantif.cpp @@ -39,7 +39,7 @@ public: class OurCheckOther : public CheckOther { public: - OurCheckOther(const Tokenizer *tokenizer, const Settings &settings, ErrorLogger *errorLogger) + OurCheckOther(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger) : CheckOther(tokenizer, settings, errorLogger) { @@ -63,7 +63,8 @@ private: errout.str(""); // Check for redundant condition.. - OurCheckOther checkOther(&tokenizer, Settings(), this); + Settings settings; + OurCheckOther checkOther(&tokenizer, &settings, this); checkOther.redundantCondition2(); } diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index 943202b06..49d20bc1c 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -47,7 +47,8 @@ private: errout.str(""); // Check for unused variables.. - CheckOther checkOther(&tokenizer, Settings(), this); + Settings settings; + CheckOther checkOther(&tokenizer, &settings, this); checkOther.CheckStructMemberUsage(); }