function variable usage : various fixes. but probably more fixes are needed.

This commit is contained in:
Daniel Marjamäki 2008-12-07 20:29:39 +00:00
parent b1ee3c5d31
commit ead97b5616
3 changed files with 63 additions and 10 deletions

View File

@ -832,6 +832,21 @@ void CheckOther::unreachableCode()
// Usage of function variables // Usage of function variables
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static bool isOp(const TOKEN *tok)
{
return bool(tok &&
(tok->str() == "&&" ||
tok->str() == "||" ||
tok->str() == "==" ||
tok->str() == "!=" ||
tok->str() == "<" ||
tok->str() == "<=" ||
tok->str() == ">" ||
tok->str() == ">=" ||
tok->str() == "<<" ||
TOKEN::Match(tok, "[+-*/&|,]")));
}
void CheckOther::functionVariableUsage() void CheckOther::functionVariableUsage()
{ {
// Parse all executing scopes.. // Parse all executing scopes..
@ -856,18 +871,29 @@ void CheckOther::functionVariableUsage()
break; break;
} }
if ( TOKEN::Match(tok, "[;{}] %type% %var% ;|=") ) if ( TOKEN::Match(tok, "[;{}] bool|char|short|int|long|float|double %var% ;|=") )
{
if ( TOKEN::Match(tok->next, "delete|return") )
varUsage[ tok->strAt(2) ] |= USAGE_READ;
else
varUsage[ tok->strAt(2) ] = USAGE_DECLARE; varUsage[ tok->strAt(2) ] = USAGE_DECLARE;
}
else if ( TOKEN::Match(tok, "[;{}] %var% =") ) else if ( TOKEN::Match(tok, "[;{}] bool|char|short|int|long|float|double * %var% ;|=") )
{ varUsage[ tok->strAt(3) ] = USAGE_DECLARE;
else if ( TOKEN::Match(tok, "delete|return %var%") )
varUsage[ tok->strAt(1) ] |= USAGE_READ;
else if ( TOKEN::Match(tok, "%var% =") )
varUsage[ tok->str() ] |= USAGE_WRITE;
else if ( TOKEN::Match(tok, "else %var% =") )
varUsage[ tok->strAt(1) ] |= USAGE_WRITE; varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
}
else if ( TOKEN::Match(tok, ">>|& %var%") )
varUsage[ tok->strAt(1) ] |= USAGE_WRITE;
else if ((TOKEN::Match(tok,"[(=&]") || isOp(tok)) && TOKEN::Match(tok->next, "%var%"))
varUsage[ tok->strAt(1) ] |= USAGE_READ;
else if (TOKEN::Match(tok, "%var%") && (tok->next->str()==")" || isOp(tok->next)))
varUsage[ tok->str() ] |= USAGE_READ;
} }
// Check usage of all variables in the current scope.. // Check usage of all variables in the current scope..

View File

@ -325,6 +325,9 @@ void CppCheck::checkFile(const std::string &code, const char FileName[])
// Unreachable code below a 'return' statement // Unreachable code below a 'return' statement
checkOther.unreachableCode(); checkOther.unreachableCode();
// Usage of local functions
checkOther.functionVariableUsage();
} }
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@ -59,6 +59,8 @@ private:
TEST_CASE( localvar1 ); TEST_CASE( localvar1 );
TEST_CASE( localvar2 ); TEST_CASE( localvar2 );
TEST_CASE( localvar3 );
TEST_CASE( localvar4 );
} }
void structmember1() void structmember1()
@ -152,6 +154,28 @@ private:
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is not assigned a value\n"), errout.str() ); ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is not assigned a value\n"), errout.str() );
} }
void localvar3()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int i;\n"
" if ( abc )\n"
" ;\n"
" else i = 0;\n"
"}\n" );
ASSERT_EQUALS( std::string("[test.cpp:2]: Variable 'i' is assigned a value that is never used\n"), errout.str() );
}
void localvar4()
{
functionVariableUsage( "void foo()\n"
"{\n"
" int i = 0;\n"
" f(i);
"}\n" );
ASSERT_EQUALS( std::string(""), errout.str() );
}
}; };