From f242c4fddd91f21846512938a14f8d6e56296d50 Mon Sep 17 00:00:00 2001 From: Reijo Tomperi Date: Tue, 11 Nov 2008 06:42:09 +0000 Subject: [PATCH] Refactoring: Following new classes were created: CheckBufferOverrunClass CheckClass CheckHeaders CheckMemoryLeakClass CheckOther Preprocessor --- CheckBufferOverrun.cpp | 15 ++++----- CheckBufferOverrun.h | 21 +++++++++--- CheckClass.cpp | 27 +++++++-------- CheckClass.h | 30 +++++++++++++---- CheckHeaders.cpp | 4 +-- CheckHeaders.h | 11 ++++--- CheckMemoryLeak.cpp | 44 ++++++++++++------------- CheckMemoryLeak.h | 32 ++++++++++++++++-- CheckOther.cpp | 31 +++++++++--------- CheckOther.h | 65 ++++++++++++++++++++----------------- Makefile | 2 +- main.cpp | 58 +++++++++++++++++++-------------- preprocessor.cpp | 27 +++++---------- preprocessor.h | 22 +++++++++++-- testbufferoverrun.cpp | 5 +-- testcharvar.cpp | 5 +-- testconstructors.cpp | 5 +-- testdivision.cpp | 5 +-- testincompletestatement.cpp | 5 +-- testmemleak.cpp | 3 +- testpreprocessor.cpp | 39 ++++++++++++++-------- testunusedprivfunc.cpp | 5 +-- testunusedvar.cpp | 3 +- 23 files changed, 279 insertions(+), 185 deletions(-) diff --git a/CheckBufferOverrun.cpp b/CheckBufferOverrun.cpp index d2961db9f..015bde6c5 100644 --- a/CheckBufferOverrun.cpp +++ b/CheckBufferOverrun.cpp @@ -21,7 +21,6 @@ //--------------------------------------------------------------------------- #include "CheckBufferOverrun.h" -#include "tokenize.h" #include "CommonCheck.h" #include @@ -40,8 +39,8 @@ static std::list CallStack; // Modified version of 'ReportError' that also reports the callstack -static void ReportError(const TOKEN *tok, const char errmsg[]) -{ +void CheckBufferOverrunClass::ReportError(const TOKEN *tok, const char errmsg[]) +{ std::ostringstream ostr; std::list::const_iterator it; for ( it = CallStack.begin(); it != CallStack.end(); it++ ) @@ -56,7 +55,7 @@ static void ReportError(const TOKEN *tok, const char errmsg[]) // Check array usage.. //--------------------------------------------------------------------------- -static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size ) +void CheckBufferOverrunClass::CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size ) { unsigned int varc = 1; while ( varname[varc] ) @@ -299,7 +298,7 @@ static void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname // Checking local variables in a scope //--------------------------------------------------------------------------- -static void CheckBufferOverrun_LocalVariable() +void CheckBufferOverrunClass::CheckBufferOverrun_LocalVariable() { int indentlevel = 0; for (const TOKEN *tok = tokens; tok; tok = tok->next) @@ -350,7 +349,7 @@ static void CheckBufferOverrun_LocalVariable() // Checking member variables of structs.. //--------------------------------------------------------------------------- -static void CheckBufferOverrun_StructVariable() +void CheckBufferOverrunClass::CheckBufferOverrun_StructVariable() { const char *declstruct_pattern[] = {"","","{",0}; for ( const TOKEN * tok = Tokenizer::findtoken( tokens, declstruct_pattern ); @@ -446,7 +445,7 @@ static void CheckBufferOverrun_StructVariable() } //--------------------------------------------------------------------------- -void CheckBufferOverrun() +void CheckBufferOverrunClass::CheckBufferOverrun() { CheckBufferOverrun_LocalVariable(); CheckBufferOverrun_StructVariable(); @@ -464,7 +463,7 @@ void CheckBufferOverrun() // Dangerous functions //--------------------------------------------------------------------------- -void WarningDangerousFunctions() +void CheckBufferOverrunClass::WarningDangerousFunctions() { for (const TOKEN *tok = tokens; tok; tok = tok->next) { diff --git a/CheckBufferOverrun.h b/CheckBufferOverrun.h index 49331ca9b..cf7f8fb76 100644 --- a/CheckBufferOverrun.h +++ b/CheckBufferOverrun.h @@ -21,14 +21,25 @@ #ifndef CheckBufferOverrunH #define CheckBufferOverrunH //--------------------------------------------------------------------------- - -// Buffer overrun.. -void CheckBufferOverrun(); + +#include "tokenize.h" + +class CheckBufferOverrunClass +{ +public: + // Buffer overrun.. + void CheckBufferOverrun(); -// Dangerous functions that can cause buffer overruns -void WarningDangerousFunctions(); + // Dangerous functions that can cause buffer overruns + void WarningDangerousFunctions(); +private: + void CheckBufferOverrun_StructVariable(); + void CheckBufferOverrun_LocalVariable(); + void CheckBufferOverrun_CheckScope( const TOKEN *tok, const char *varname[], const int size, const int total_size ); + void ReportError(const TOKEN *tok, const char errmsg[]); +}; //--------------------------------------------------------------------------- #endif diff --git a/CheckClass.cpp b/CheckClass.cpp index 4a4c2d3ac..e3d61dd52 100644 --- a/CheckClass.cpp +++ b/CheckClass.cpp @@ -18,10 +18,10 @@ //--------------------------------------------------------------------------- #include "CheckClass.h" -#include "tokenize.h" + #include "CommonCheck.h" #include -#include + #include #include #include @@ -36,15 +36,10 @@ extern bool CheckCodingStyle; -struct VAR -{ - const char *name; - bool init; - struct VAR *next; -}; + //--------------------------------------------------------------------------- -static struct VAR *ClassChecking_GetVarList(const TOKEN *tok1) +struct VAR *CheckClass::ClassChecking_GetVarList(const TOKEN *tok1) { // Get variable list.. struct VAR *varlist = NULL; @@ -106,7 +101,7 @@ static struct VAR *ClassChecking_GetVarList(const TOKEN *tok1) } //--------------------------------------------------------------------------- -static const TOKEN * FindClassFunction( const TOKEN *tok, const char classname[], const char funcname[], int &indentlevel ) +const TOKEN * CheckClass::FindClassFunction( const TOKEN *tok, const char classname[], const char funcname[], int &indentlevel ) { const char *_classname[2] = {0,0}; const char *_funcname[2] = {0,0}; @@ -186,7 +181,7 @@ static const TOKEN * FindClassFunction( const TOKEN *tok, const char classname[] } //--------------------------------------------------------------------------- -static void InitVar(struct VAR *varlist, const char varname[]) +void CheckClass::InitVar(struct VAR *varlist, const char varname[]) { for (struct VAR *var = varlist; var; var = var->next) { @@ -199,7 +194,7 @@ static void InitVar(struct VAR *varlist, const char varname[]) } //--------------------------------------------------------------------------- -static void ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *ftok, struct VAR *varlist, const char classname[], std::list &callstack) +void CheckClass::ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *ftok, struct VAR *varlist, const char classname[], std::list &callstack) { bool Assign = false; unsigned int indentlevel = 0; @@ -304,7 +299,7 @@ static void ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *fto // ClassCheck: Check that all class constructors are ok. //--------------------------------------------------------------------------- -void CheckConstructors() +void CheckClass::CheckConstructors() { // Locate class const char *pattern_classname[] = {"class","","{",NULL}; @@ -404,7 +399,7 @@ void CheckConstructors() // ClassCheck: Unused private functions //--------------------------------------------------------------------------- -void CheckUnusedPrivateFunctions() +void CheckClass::CheckUnusedPrivateFunctions() { // Locate some class const char *pattern_class[] = {"class","","{",NULL}; @@ -538,7 +533,7 @@ void CheckUnusedPrivateFunctions() // ClassCheck: Check that memset is not used on classes //--------------------------------------------------------------------------- -void CheckMemset() +void CheckClass::CheckMemset() { // Locate all 'memset' tokens.. for (const TOKEN *tok = tokens; tok; tok = tok->next) @@ -600,7 +595,7 @@ void CheckMemset() // ClassCheck: "void operator=(" //--------------------------------------------------------------------------- -void CheckOperatorEq1() +void CheckClass::CheckOperatorEq1() { const char *pattern[] = {"void", "operator", "=", "(", NULL}; if (const TOKEN *tok = Tokenizer::findtoken(tokens,pattern)) diff --git a/CheckClass.h b/CheckClass.h index 0438a642a..c3b7f64e3 100644 --- a/CheckClass.h +++ b/CheckClass.h @@ -20,16 +20,34 @@ #ifndef CheckClassH #define CheckClassH //--------------------------------------------------------------------------- + +#include "tokenize.h" +#include + +struct VAR +{ + const char *name; + bool init; + struct VAR *next; +}; +class CheckClass +{ +public: + void CheckConstructors(); -void CheckConstructors(); + void CheckUnusedPrivateFunctions(); -void CheckUnusedPrivateFunctions(); - -void CheckMemset(); - -void CheckOperatorEq1(); // Warning upon "void operator=(.." + void CheckMemset(); + void CheckOperatorEq1(); // Warning upon "void operator=(.." + +private: + void ClassChecking_VarList_Initialize(const TOKEN *tok1, const TOKEN *ftok, struct VAR *varlist, const char classname[], std::list &callstack); + void InitVar(struct VAR *varlist, const char varname[]); + const TOKEN *FindClassFunction( const TOKEN *tok, const char classname[], const char funcname[], int &indentlevel ); + struct VAR *ClassChecking_GetVarList(const TOKEN *tok1); +}; //--------------------------------------------------------------------------- #endif diff --git a/CheckHeaders.cpp b/CheckHeaders.cpp index 6bc36d639..c0f39b7d8 100644 --- a/CheckHeaders.cpp +++ b/CheckHeaders.cpp @@ -35,7 +35,7 @@ // HEADERS - No implementation in a header //--------------------------------------------------------------------------- -void WarningHeaderWithImplementation() +void CheckHeaders::WarningHeaderWithImplementation() { for (TOKEN *tok = tokens; tok; tok = tok->next) { @@ -69,7 +69,7 @@ void WarningHeaderWithImplementation() // HEADERS - Unneeded include //--------------------------------------------------------------------------- -void WarningIncludeHeader() +void CheckHeaders::WarningIncludeHeader() { // Including.. for (TOKEN *includetok = tokens; includetok; includetok = includetok->next) diff --git a/CheckHeaders.h b/CheckHeaders.h index 0c488d06b..6d72277a4 100644 --- a/CheckHeaders.h +++ b/CheckHeaders.h @@ -21,11 +21,14 @@ #ifndef CheckHeadersH #define CheckHeadersH //--------------------------------------------------------------------------- + +class CheckHeaders +{ +public: + void WarningHeaderWithImplementation(); + void WarningIncludeHeader(); -void WarningHeaderWithImplementation(); - -void WarningIncludeHeader(); - +}; //--------------------------------------------------------------------------- #endif diff --git a/CheckMemoryLeak.cpp b/CheckMemoryLeak.cpp index e98211a86..cf6638c2a 100644 --- a/CheckMemoryLeak.cpp +++ b/CheckMemoryLeak.cpp @@ -19,14 +19,14 @@ #include "CheckMemoryLeak.h" -#include "tokenize.h" + #include "CommonCheck.h" #include // free #include -#include + #include #ifdef __BORLANDC__ @@ -40,10 +40,8 @@ #endif //--------------------------------------------------------------------------- -static TOKEN *getcode(const TOKEN *tok, const char varname[]); -static void simplifycode(TOKEN *tok); -static bool isclass( const std::string &typestr ) +bool CheckMemoryLeakClass::isclass( const std::string &typestr ) { if ( typestr == "char" || typestr == "short" || @@ -63,7 +61,7 @@ static bool isclass( const std::string &typestr ) //--------------------------------------------------------------------------- -enum AllocType { No, Malloc, gMalloc, New, NewA }; + // Extra allocation.. class AllocFunc @@ -80,7 +78,7 @@ class AllocFunc }; static std::list listallocfunc; -static AllocType GetAllocationType( const TOKEN *tok2 ) +AllocType CheckMemoryLeakClass::GetAllocationType( const TOKEN *tok2 ) { // What we may have... // * var = (char *)malloc(10); @@ -149,7 +147,7 @@ static AllocType GetAllocationType( const TOKEN *tok2 ) return No; } -static AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] ) +AllocType CheckMemoryLeakClass::GetDeallocationType( const TOKEN *tok, const char *varnames[] ) { // Redundant condition.. if ( Match(tok, "if ( %var1% )", varnames) ) @@ -180,7 +178,7 @@ static AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] ) static std::list callstack; -static const char * call_func( const TOKEN *tok, const char *varnames[] ) +const char * CheckMemoryLeakClass::call_func( const TOKEN *tok, const char *varnames[] ) { if (Match(tok,"if") || Match(tok,"for") || Match(tok,"while")) return 0; @@ -238,7 +236,7 @@ static const char * call_func( const TOKEN *tok, const char *varnames[] ) //-------------------------------------------------------------------------- -static void MismatchError( const TOKEN *Tok1, const char varname[] ) +void CheckMemoryLeakClass::MismatchError( const TOKEN *Tok1, const char varname[] ) { std::ostringstream errmsg; errmsg << FileLine(Tok1) << ": Mismatching allocation and deallocation: " << varname; @@ -246,7 +244,7 @@ static void MismatchError( const TOKEN *Tok1, const char varname[] ) } //--------------------------------------------------------------------------- -static void MemoryLeak( const TOKEN *tok, const char varname[] ) +void CheckMemoryLeakClass::MemoryLeak( const TOKEN *tok, const char varname[] ) { std::ostringstream errmsg; errmsg << FileLine(tok) << ": Memory leak: " << varname; @@ -254,7 +252,7 @@ static void MemoryLeak( const TOKEN *tok, const char varname[] ) } //--------------------------------------------------------------------------- -static void instoken(TOKEN *tok, const char str[]) +void CheckMemoryLeakClass::instoken(TOKEN *tok, const char str[]) { TOKEN *newtok = new TOKEN; newtok->setstr(str); @@ -263,7 +261,7 @@ static void instoken(TOKEN *tok, const char str[]) } //--------------------------------------------------------------------------- -static bool notvar(const TOKEN *tok, const char *varnames[]) +bool CheckMemoryLeakClass::notvar(const TOKEN *tok, const char *varnames[]) { return bool( Match(tok, "! %var1% [;)&|]", varnames) || Match(tok, "! ( %var1% )", varnames) || @@ -283,7 +281,7 @@ extern bool ShowAll; * varname - name of variable */ -static TOKEN *getcode(const TOKEN *tok, const char varname[]) +TOKEN *CheckMemoryLeakClass::getcode(const TOKEN *tok, const char varname[]) { const char *varnames[2]; varnames[0] = varname; @@ -462,7 +460,7 @@ static TOKEN *getcode(const TOKEN *tok, const char varname[]) return rethead; } -static void erase(TOKEN *begin, const TOKEN *end) +void CheckMemoryLeakClass::erase(TOKEN *begin, const TOKEN *end) { if ( ! begin ) return; @@ -481,7 +479,7 @@ static void erase(TOKEN *begin, const TOKEN *end) * Simplify code * \param tok first token */ -static void simplifycode(TOKEN *tok) +void CheckMemoryLeakClass::simplifycode(TOKEN *tok) { // Remove "do"... // do { x } while (y); @@ -758,7 +756,7 @@ static void simplifycode(TOKEN *tok) // Simpler but less powerful than "CheckMemoryLeak_CheckScope_All" -static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] ) +void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] ) { callstack.clear(); @@ -826,7 +824,7 @@ static void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] // Checks for memory leaks inside function.. //--------------------------------------------------------------------------- -static void CheckMemoryLeak_InFunction() +void CheckMemoryLeakClass::CheckMemoryLeak_InFunction() { bool infunc = false; int indentlevel = 0; @@ -868,11 +866,9 @@ static void CheckMemoryLeak_InFunction() // Checks for memory leaks in classes.. //--------------------------------------------------------------------------- -static void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector &classname ); -static void CheckMemoryLeak_ClassMembers_Variable( const std::vector &classname, const char varname[] ); -static void CheckMemoryLeak_ClassMembers() +void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers() { int indentlevel = 0; for ( const TOKEN *tok = tokens; tok; tok = tok->next ) @@ -893,7 +889,7 @@ static void CheckMemoryLeak_ClassMembers() } -static void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector &classname ) +void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector &classname ) { // Go into class. while ( tok1 && tok1->str[0] != '{' ) @@ -938,7 +934,7 @@ static void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vec } } -static void CheckMemoryLeak_ClassMembers_Variable( const std::vector &classname, const char varname[] ) +void CheckMemoryLeakClass::CheckMemoryLeak_ClassMembers_Variable( const std::vector &classname, const char varname[] ) { // Function pattern.. Check if member function std::ostringstream fpattern; @@ -1035,7 +1031,7 @@ static void CheckMemoryLeak_ClassMembers_Variable( const std::vector +#include "tokenize.h" + +enum AllocType { No, Malloc, gMalloc, New, NewA }; + +class CheckMemoryLeakClass +{ +public: + void CheckMemoryLeak(); + +private: + void CheckMemoryLeak_ClassMembers_Variable( const std::vector &classname, const char varname[] ); + void CheckMemoryLeak_ClassMembers_ParseClass( const TOKEN *tok1, std::vector &classname ); + void CheckMemoryLeak_ClassMembers(); + void CheckMemoryLeak_InFunction(); + void CheckMemoryLeak_CheckScope( const TOKEN *Tok1, const char varname[] ); + void simplifycode(TOKEN *tok); + void erase(TOKEN *begin, const TOKEN *end); + + TOKEN *getcode(const TOKEN *tok, const char varname[]); + bool notvar(const TOKEN *tok, const char *varnames[]); + void instoken(TOKEN *tok, const char str[]); + void MemoryLeak( const TOKEN *tok, const char varname[] ); + void MismatchError( const TOKEN *Tok1, const char varname[] ); + const char * call_func( const TOKEN *tok, const char *varnames[] ); + AllocType GetDeallocationType( const TOKEN *tok, const char *varnames[] ); + AllocType GetAllocationType( const TOKEN *tok2 ); + bool isclass( const std::string &typestr ); +}; //--------------------------------------------------------------------------- #endif diff --git a/CheckOther.cpp b/CheckOther.cpp index b4bde6f1f..b66a2b157 100644 --- a/CheckOther.cpp +++ b/CheckOther.cpp @@ -19,7 +19,7 @@ //--------------------------------------------------------------------------- #include "CheckOther.h" -#include "tokenize.h" + #include "CommonCheck.h" #include #include @@ -35,7 +35,7 @@ // Warning on C-Style casts.. p = (kalle *)foo; //--------------------------------------------------------------------------- -void WarningOldStylePointerCast() +void CheckOther::WarningOldStylePointerCast() { for (const TOKEN *tok = tokens; tok; tok = tok->next) { @@ -62,7 +62,7 @@ void WarningOldStylePointerCast() // Use standard function "isdigit" instead //--------------------------------------------------------------------------- -void WarningIsDigit() +void CheckOther::WarningIsDigit() { for (const TOKEN *tok = tokens; tok; tok = tok->next) { @@ -87,7 +87,7 @@ void WarningIsDigit() // Use standard function "isalpha" instead //--------------------------------------------------------------------------- -void WarningIsAlpha() +void CheckOther::WarningIsAlpha() { for (const TOKEN *tok = tokens; tok; tok = tok->next) { @@ -145,7 +145,7 @@ void WarningIsAlpha() // Redundant code.. //--------------------------------------------------------------------------- -void WarningRedundantCode() +void CheckOther::WarningRedundantCode() { // if (p) delete p @@ -207,7 +207,7 @@ void WarningRedundantCode() // if (condition) .... //--------------------------------------------------------------------------- -void WarningIf() +void CheckOther::WarningIf() { // Search for 'if (condition);' @@ -298,7 +298,7 @@ void WarningIf() // strtol(str, 0, radix) <- radix must be 0 or 2-36 //--------------------------------------------------------------------------- -void InvalidFunctionUsage() +void CheckOther::InvalidFunctionUsage() { for ( const TOKEN *tok = tokens; tok; tok = tok->next ) { @@ -342,7 +342,7 @@ void InvalidFunctionUsage() // Assignment in condition //--------------------------------------------------------------------------- -void CheckIfAssignment() +void CheckOther::CheckIfAssignment() { for (const TOKEN *tok = tokens; tok; tok = tok->next) { @@ -363,7 +363,7 @@ void CheckIfAssignment() // Check for unsigned divisions //--------------------------------------------------------------------------- -void CheckUnsignedDivision() +void CheckOther::CheckUnsignedDivision() { // Check for "ivar / uvar" and "uvar / ivar" std::map varsign; @@ -428,9 +428,8 @@ void CheckUnsignedDivision() // Check scope of variables.. //--------------------------------------------------------------------------- -static void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] ); -void CheckVariableScope() +void CheckOther::CheckVariableScope() { // Walk through all tokens.. bool func = false; @@ -512,7 +511,7 @@ void CheckVariableScope() } //--------------------------------------------------------------------------- -static void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] ) +void CheckOther::CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] ) { const TOKEN *tok = tok1; @@ -585,7 +584,7 @@ static void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[ // Check for constant function parameters //--------------------------------------------------------------------------- -void CheckConstantFunctionParameter() +void CheckOther::CheckConstantFunctionParameter() { for (const TOKEN *tok = tokens; tok; tok = tok->next) { @@ -624,7 +623,7 @@ void CheckConstantFunctionParameter() // Check that all struct members are used //--------------------------------------------------------------------------- -void CheckStructMemberUsage() +void CheckOther::CheckStructMemberUsage() { const char *structname = 0; @@ -687,7 +686,7 @@ void CheckStructMemberUsage() // Check usage of char variables.. //--------------------------------------------------------------------------- -void CheckCharVariable() +void CheckOther::CheckCharVariable() { for (const TOKEN *tok = tokens; tok; tok = tok->next) { @@ -741,7 +740,7 @@ void CheckCharVariable() // Incomplete statement.. //--------------------------------------------------------------------------- -void CheckIncompleteStatement() +void CheckOther::CheckIncompleteStatement() { int parlevel = 0; diff --git a/CheckOther.h b/CheckOther.h index bdea05548..11350fd79 100644 --- a/CheckOther.h +++ b/CheckOther.h @@ -22,49 +22,56 @@ #ifndef CheckOtherH #define CheckOtherH //--------------------------------------------------------------------------- + +#include "tokenize.h" +class CheckOther +{ +public: + // Casting + void WarningOldStylePointerCast(); -// Casting -void WarningOldStylePointerCast(); + // Use standard functions instead + void WarningIsDigit(); -// Use standard functions instead -void WarningIsDigit(); + // Use standard functions instead + void WarningIsAlpha(); -// Use standard functions instead -void WarningIsAlpha(); + // Redundant code + void WarningRedundantCode(); -// Redundant code -void WarningRedundantCode(); + // Warning upon: if (condition); + void WarningIf(); -// Warning upon: if (condition); -void WarningIf(); + // Assignment in condition + void CheckIfAssignment(); -// Assignment in condition -void CheckIfAssignment(); + // Using dangerous functions + void WarningDangerousFunctions(); -// Using dangerous functions -void WarningDangerousFunctions(); + // Invalid function usage.. + void InvalidFunctionUsage(); -// Invalid function usage.. -void InvalidFunctionUsage(); + // Check for unsigned division that might create bad results + void CheckUnsignedDivision(); -// Check for unsigned division that might create bad results -void CheckUnsignedDivision(); + // Check scope of variables + void CheckVariableScope(); -// Check scope of variables -void CheckVariableScope(); + // Check for constant function parameter + void CheckConstantFunctionParameter(); -// Check for constant function parameter -void CheckConstantFunctionParameter(); + // Check that all struct members are used + void CheckStructMemberUsage(); -// Check that all struct members are used -void CheckStructMemberUsage(); + // Using char variable as array index / as operand in bit operation + void CheckCharVariable(); -// Using char variable as array index / as operand in bit operation -void CheckCharVariable(); - -// Incomplete statement. A statement that only contains a constant or variable -void CheckIncompleteStatement(); + // Incomplete statement. A statement that only contains a constant or variable + void CheckIncompleteStatement(); +private: + void CheckVariableScope_LookupVar( const TOKEN *tok1, const char varname[] ); +}; //--------------------------------------------------------------------------- #endif diff --git a/Makefile b/Makefile index e427fb0f1..d2e07cc26 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ all: ${OBJS} main.o test: ${OBJS} testrunner.o testsuite.o ${TESTS} g++ -Wall -g -o testrunner $^ clean: - rm -f *.o cppcheck_test cppcheck + rm -f *.o testrunner cppcheck install: cppcheck install -d ${BIN} install cppcheck ${BIN} diff --git a/main.cpp b/main.cpp index f9a6df1a1..e38a64d80 100644 --- a/main.cpp +++ b/main.cpp @@ -126,8 +126,9 @@ int main(int argc, char* argv[]) std::cout << "Checking " << fname << "...\n"; std::ifstream fin( fname.c_str() ); - std::map code; - preprocess(fin, code, fname); + std::map code; + Preprocessor preprocessor; + preprocessor.preprocess(fin, code, fname); for ( std::map::const_iterator it = code.begin(); it != code.end(); ++it ) CppCheck(it->second, filenames[c].c_str(), c); @@ -176,39 +177,46 @@ static void CppCheck(const std::string &code, const char FileName[], unsigned in // Check that the memsets are valid. // The 'memset' function can do dangerous things if used wrong. // Important: The checking doesn't work on simplified tokens list. - CheckMemset(); + CheckClass checkClass; + checkClass.CheckMemset(); // Check for unsigned divisions where one operand is signed // Very important to run it before 'SimplifyTokenList' - CheckUnsignedDivision(); + CheckOther checkOther; + checkOther.CheckUnsignedDivision(); // Give warning when using char variable as array index // Doesn't work on simplified token list ('unsigned') if ( ShowAll ) - CheckCharVariable(); + checkOther.CheckCharVariable(); // Including header which is not needed (too many false positives) - //if ( CheckCodingStyle ) - // WarningIncludeHeader(); +// if ( CheckCodingStyle ) +// { +// CheckHeaders checkHeaders; +// checkHeaders.WarningIncludeHeader(); +// } tokenizer.SimplifyTokenList(); - // Memory leak - CheckMemoryLeak(); + // Memory leak + CheckMemoryLeakClass checkMemoryLeak; + checkMemoryLeak.CheckMemoryLeak(); - // Buffer overruns.. - CheckBufferOverrun(); + // Buffer overruns.. + CheckBufferOverrunClass checkBufferOverrun; + checkBufferOverrun.CheckBufferOverrun(); // Check that all class constructors are ok. - CheckConstructors(); + checkClass.CheckConstructors(); if (ShowAll) { // Check for "if (a=b)" - CheckIfAssignment(); + checkOther.CheckIfAssignment(); // Check for case without break // Disabled because it generates many false positives @@ -222,47 +230,47 @@ static void CppCheck(const std::string &code, const char FileName[], unsigned in // Dangerous functions, such as 'gets' and 'scanf' - WarningDangerousFunctions(); + checkBufferOverrun.WarningDangerousFunctions(); // Invalid function usage.. - InvalidFunctionUsage(); + checkOther.InvalidFunctionUsage(); if (CheckCodingStyle) { // Check that all private functions are called. - CheckUnusedPrivateFunctions(); + checkClass.CheckUnusedPrivateFunctions(); // Warning upon c-style pointer casts const char *ext = strrchr(FileName, '.'); if (ext && strcmp(ext,".cpp")==0) - WarningOldStylePointerCast(); + checkOther.WarningOldStylePointerCast(); // Use standard functions instead - WarningIsDigit(); - WarningIsAlpha(); + checkOther.WarningIsDigit(); + checkOther.WarningIsAlpha(); - CheckOperatorEq1(); + checkClass.CheckOperatorEq1(); // if (a) delete a; - WarningRedundantCode(); + checkOther.WarningRedundantCode(); // if (condition); - WarningIf(); + checkOther.WarningIf(); // Variable scope (check if the scope could be limited) //CheckVariableScope(); // Check if a constant function parameter is passed by value - CheckConstantFunctionParameter(); + checkOther.CheckConstantFunctionParameter(); // Unused struct members.. - CheckStructMemberUsage(); + checkOther.CheckStructMemberUsage(); // Check for various types of incomplete statements that could for example // mean that an ';' has been added by accident - CheckIncompleteStatement(); + checkOther.CheckIncompleteStatement(); } // Clean up tokens.. diff --git a/preprocessor.cpp b/preprocessor.cpp index 4a8d92bb4..79742f8f8 100644 --- a/preprocessor.cpp +++ b/preprocessor.cpp @@ -21,7 +21,7 @@ #include "CommonCheck.h" #include -#include + #include #ifdef __BORLANDC__ @@ -29,15 +29,6 @@ #endif -/** - * Get all possible configurations. By looking at the ifdefs and ifndefs in filedata - */ -static std::list getcfgs( const std::string &filedata ); - -/** - * Get preprocessed code for a given configuration - */ -static std::string getcode(const std::string &filedata, std::string cfg); /** @@ -45,7 +36,7 @@ static std::string getcode(const std::string &filedata, std::string cfg); * \param istr The (file/string) stream to read from. * \param result The map that will get the results */ -void preprocess(std::istream &istr, std::map &result, const std::string &filename) +void Preprocessor::preprocess(std::istream &istr, std::map &result, const std::string &filename) { // Get filedata from stream.. bool ignoreSpace = true; @@ -178,7 +169,7 @@ void preprocess(std::istream &istr, std::map &result, // Get the DEF in this line: "#ifdef DEF" -static std::string getdef(std::string line, bool def) +std::string Preprocessor::getdef(std::string line, bool def) { // If def is true, the line must start with "#ifdef" if ( def && line.find("#ifdef ") != 0 && line.find("#if ") != 0 && line.find("#elif ") != 0 ) @@ -205,7 +196,7 @@ static std::string getdef(std::string line, bool def) -static std::list getcfgs( const std::string &filedata ) +std::list Preprocessor::getcfgs( const std::string &filedata ) { std::list ret; ret.push_back(""); @@ -254,7 +245,7 @@ static std::list getcfgs( const std::string &filedata ) -static bool match_cfg_def( std::string cfg, const std::string &def ) +bool Preprocessor::match_cfg_def( std::string cfg, const std::string &def ) { if ( def == "0" ) return false; @@ -271,7 +262,7 @@ static bool match_cfg_def( std::string cfg, const std::string &def ) return bool(cfg == def); std::string _cfg = cfg.substr( 0, cfg.find(";") ); if ( _cfg == def ) - return true; + return true; cfg.erase( 0, cfg.find(";") + 1 ); } @@ -279,7 +270,7 @@ static bool match_cfg_def( std::string cfg, const std::string &def ) } -static std::string getcode(const std::string &filedata, std::string cfg) +std::string Preprocessor::getcode(const std::string &filedata, std::string cfg) { std::ostringstream ret; @@ -313,13 +304,13 @@ static std::string getcode(const std::string &filedata, std::string cfg) else if ( ! def.empty() ) { matching_ifdef.push_back( match_cfg_def(cfg, def) ); - matched_ifdef.push_back( matching_ifdef.back() ); + matched_ifdef.push_back( matching_ifdef.back() ); } else if ( ! ndef.empty() ) { matching_ifdef.push_back( ! match_cfg_def(cfg, ndef) ); - matched_ifdef.push_back( matching_ifdef.back() ); + matched_ifdef.push_back( matching_ifdef.back() ); } else if ( line == "#else" ) diff --git a/preprocessor.h b/preprocessor.h index 759fb4821..1154fb217 100644 --- a/preprocessor.h +++ b/preprocessor.h @@ -24,9 +24,27 @@ #include #include #include +#include - -void preprocess(std::istream &istr, std::map &result, const std::string &filename); +class Preprocessor +{ +public: + void preprocess(std::istream &istr, std::map &result, const std::string &filename); +private: + /** + * Get preprocessed code for a given configuration + */ + std::string getcode(const std::string &filedata, std::string cfg); + + /** + * Get all possible configurations. By looking at the ifdefs and ifndefs in filedata + */ + std::list getcfgs( const std::string &filedata ); + + std::string getdef(std::string line, bool def); + + bool match_cfg_def( std::string cfg, const std::string &def ); +}; //--------------------------------------------------------------------------- #endif diff --git a/testbufferoverrun.cpp b/testbufferoverrun.cpp index 156584d92..9647657ef 100644 --- a/testbufferoverrun.cpp +++ b/testbufferoverrun.cpp @@ -51,8 +51,9 @@ private: errout.str(""); // Check for memory leaks.. - ShowAll = true; - CheckBufferOverrun(); + ShowAll = true; + CheckBufferOverrunClass checkBufferOverrun; + checkBufferOverrun.CheckBufferOverrun(); tokenizer.DeallocateTokens(); } diff --git a/testcharvar.cpp b/testcharvar.cpp index 828954038..c61f48570 100644 --- a/testcharvar.cpp +++ b/testcharvar.cpp @@ -56,8 +56,9 @@ private: errout.str(""); // Check for memory leaks.. - ShowAll = true; - CheckCharVariable(); + ShowAll = true; + CheckOther checkOther; + checkOther.CheckCharVariable(); tokenizer.DeallocateTokens(); } diff --git a/testconstructors.cpp b/testconstructors.cpp index a667b1253..22e4c456a 100644 --- a/testconstructors.cpp +++ b/testconstructors.cpp @@ -45,8 +45,9 @@ private: // Clear the error buffer.. errout.str(""); - // Check for memory leaks.. - CheckConstructors(); + // Check for memory leaks.. + CheckClass checkClass; + checkClass.CheckConstructors(); tokenizer.DeallocateTokens(); } diff --git a/testdivision.cpp b/testdivision.cpp index 5ff51cd17..31ffd11bb 100644 --- a/testdivision.cpp +++ b/testdivision.cpp @@ -50,8 +50,9 @@ private: errout.str(""); // Check for memory leaks.. - ShowAll = true; - CheckUnsignedDivision(); + ShowAll = true; + CheckOther checkOther; + checkOther.CheckUnsignedDivision(); tokenizer.DeallocateTokens(); } diff --git a/testincompletestatement.cpp b/testincompletestatement.cpp index 06e9ff080..64c91f2ef 100644 --- a/testincompletestatement.cpp +++ b/testincompletestatement.cpp @@ -47,8 +47,9 @@ private: // Clear the error buffer.. errout.str(""); - // Check for unused variables.. - CheckIncompleteStatement(); + // Check for unused variables.. + CheckOther checkOther; + checkOther.CheckIncompleteStatement(); tokenizer.DeallocateTokens(); } diff --git a/testmemleak.cpp b/testmemleak.cpp index 0f6cc20a9..6cbcabf61 100644 --- a/testmemleak.cpp +++ b/testmemleak.cpp @@ -51,7 +51,8 @@ private: // Check for memory leaks.. ShowAll = false; FillFunctionList(0); - CheckMemoryLeak(); + CheckMemoryLeakClass checkMemoryLeak; + checkMemoryLeak.CheckMemoryLeak(); tokenizer.DeallocateTokens(); } diff --git a/testpreprocessor.cpp b/testpreprocessor.cpp index 46ddecb44..9edfb61af 100644 --- a/testpreprocessor.cpp +++ b/testpreprocessor.cpp @@ -140,7 +140,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -163,7 +164,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -185,7 +187,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -210,7 +213,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -233,7 +237,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -259,7 +264,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -281,7 +287,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -303,7 +310,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -322,7 +330,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -346,7 +355,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -365,7 +375,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -389,7 +400,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); @@ -408,7 +420,8 @@ private: // Preprocess => actual result.. std::istringstream istr(filedata); std::map actual; - preprocess( istr, actual, "" ); + Preprocessor preprocessor; + preprocessor.preprocess( istr, actual, "" ); // Compare results.. ASSERT_EQUALS( true, cmpmaps(actual, expected)); diff --git a/testunusedprivfunc.cpp b/testunusedprivfunc.cpp index 04dd39a8d..fafbefd45 100644 --- a/testunusedprivfunc.cpp +++ b/testunusedprivfunc.cpp @@ -50,8 +50,9 @@ private: // Clear the error buffer.. errout.str(""); - // Check for unused private functions.. - CheckUnusedPrivateFunctions(); + // Check for unused private functions.. + CheckClass checkClass; + checkClass.CheckUnusedPrivateFunctions(); tokenizer.DeallocateTokens(); } diff --git a/testunusedvar.cpp b/testunusedvar.cpp index 01bd5eb88..233bac99a 100644 --- a/testunusedvar.cpp +++ b/testunusedvar.cpp @@ -48,7 +48,8 @@ private: errout.str(""); // Check for unused variables.. - CheckStructMemberUsage(); + CheckOther checkOther; + checkOther.CheckStructMemberUsage(); tokenizer.DeallocateTokens(); }