From 219d82e180ae70063aedae5497b43f6a48691937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 9 May 2008 18:29:42 +0000 Subject: [PATCH] CheckStructMemberUsage: Check for unused struct members --- CheckOther.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++ CheckOther.h | 3 +++ main.cpp | 5 ++++- tests.cpp | 14 +++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/CheckOther.cpp b/CheckOther.cpp index d48c8af47..32315d41e 100644 --- a/CheckOther.cpp +++ b/CheckOther.cpp @@ -732,4 +732,60 @@ void CheckConstantFunctionParameter() } } } +//--------------------------------------------------------------------------- + + + +//--------------------------------------------------------------------------- +// Check that all struct members are used +//--------------------------------------------------------------------------- + +void CheckStructMemberUsage() +{ + const char *structname = 0; + + for ( const TOKEN *tok = tokens; tok; tok = tok->next ) + { + if ( tok->FileIndex != 0 ) + continue; + if ( tok->str[0] == '}' ) + structname = 0; + if ( Match(tok, "struct %type% {") ) + structname = getstr(tok, 1); + + if (structname && Match(tok, "[{;]")) + { + const char *varname = 0; + if (Match(tok->next, "%type% %var% ;")) + varname = getstr( tok, 2 ); + else + continue; + + const char *varnames[2]; + varnames[0] = varname; + varnames[1] = 0; + bool used = false; + for ( const TOKEN *tok2 = tokens; tok2; tok2 = tok2->next ) + { + if ( tok->FileIndex != 0 ) + continue; + + if (Match(tok2, ". %var%", varnames)) + { + if ( strcmp("=", getstr(tok2,2)) == 0 ) + continue; + used = true; + break; + } + } + + if ( ! used ) + { + std::ostringstream errmsg; + errmsg << FileLine(tok) << ": struct member '" << structname << "::" << varname << "' is never read"; + ReportErr(errmsg.str()); + } + } + } +} diff --git a/CheckOther.h b/CheckOther.h index 07e376bb2..d8c90b9ed 100644 --- a/CheckOther.h +++ b/CheckOther.h @@ -43,6 +43,9 @@ void CheckVariableScope(); // Check for constant function parameter void CheckConstantFunctionParameter(); +// Check that all struct members are used +void CheckStructMemberUsage(); + //--------------------------------------------------------------------------- #endif diff --git a/main.cpp b/main.cpp index 21524102b..ed5ccf0aa 100644 --- a/main.cpp +++ b/main.cpp @@ -300,7 +300,10 @@ static void CppCheck(const char FileName[], unsigned int FileId) CheckVariableScope(); // Check if a constant function parameter is passed by value - CheckConstantFunctionParameter(); + CheckConstantFunctionParameter(); + + // Unused struct members.. + CheckStructMemberUsage(); } // Clean up tokens.. diff --git a/tests.cpp b/tests.cpp index 54ea3a94a..614b6092d 100644 --- a/tests.cpp +++ b/tests.cpp @@ -29,6 +29,7 @@ static void memleak_in_class(); static void division(); static void unused_variable(); static void fpar_byvalue(); +static void unused_struct_member(); //--------------------------------------------------------------------------- int main() @@ -61,6 +62,9 @@ int main() unused_variable(); fpar_byvalue(); + + // unused struct member.. + unused_struct_member(); std::cout << "Success Rate: " << SuccessCount @@ -925,3 +929,13 @@ static void fpar_byvalue() } //--------------------------------------------------------------------------- +static void unused_struct_member() +{ + check( CheckStructMemberUsage, + __LINE__, + "struct abc {int i;};", + "[test.cpp:1]: struct member 'abc::i' is never read\n" ); +} + + +