class checking: Checking that vectors/lists/strings etc are modified in the assignment function

This commit is contained in:
Daniel Marjamäki 2009-05-01 07:28:58 +02:00
parent 7e5c32b7f4
commit 534d0e9939
3 changed files with 38 additions and 20 deletions

View File

@ -42,7 +42,7 @@ CheckClass instance;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1) struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1, bool withClasses)
{ {
// Get variable list.. // Get variable list..
struct VAR *varlist = NULL; struct VAR *varlist = NULL;
@ -84,7 +84,9 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1)
// Is it a variable declaration? // Is it a variable declaration?
else if (Token::Match(next, "%type% %var% ;")) else if (Token::Match(next, "%type% %var% ;"))
{ {
if (next->isStandardType()) if (withClasses)
varname = next->strAt(1);
else if (next->isStandardType())
varname = next->strAt(1); varname = next->strAt(1);
else if (Token::findmatch(_tokenizer->tokens(), ("enum " + next->str()).c_str())) else if (Token::findmatch(_tokenizer->tokens(), ("enum " + next->str()).c_str()))
varname = next->strAt(1); varname = next->strAt(1);
@ -102,6 +104,21 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1)
varname = next->strAt(3); varname = next->strAt(3);
} }
// std::string..
else if (withClasses && Token::Match(next, "std :: string %var% ;"))
{
varname = next->strAt(3);
}
// Container..
else if (withClasses && Token::Match(next, "std :: %type% <"))
{
while (next && next->str() != ">")
next = next->next();
if (Token::Match(next, "> %var% ;"))
varname = next->strAt(1);
}
// If the varname was set in one of the two if-block above, create a entry for this variable.. // If the varname was set in one of the two if-block above, create a entry for this variable..
if (varname) if (varname)
{ {
@ -309,7 +326,7 @@ void CheckClass::constructors()
if (ErrorLogger::noConstructor(*_settings)) if (ErrorLogger::noConstructor(*_settings))
{ {
// If the class has member variables there should be an constructor // If the class has member variables there should be an constructor
struct VAR *varlist = ClassChecking_GetVarList(tok1); struct VAR *varlist = ClassChecking_GetVarList(tok1, false);
if (varlist) if (varlist)
{ {
noConstructorError(tok1, classNameToken->str()); noConstructorError(tok1, classNameToken->str());
@ -327,31 +344,24 @@ void CheckClass::constructors()
continue; continue;
} }
// Check that all member variables are initialized..
struct VAR *varlist = ClassChecking_GetVarList(tok1);
// Check constructors // Check constructors
CheckConstructors(tok1, varlist, className[0]); CheckConstructors(tok1, className[0]);
// Check assignment operators // Check assignment operators
CheckConstructors(tok1, varlist, "operator ="); CheckConstructors(tok1, "operator =");
// Delete the varlist..
while (varlist)
{
struct VAR *nextvar = varlist->next;
delete varlist;
varlist = nextvar;
}
tok1 = Token::findmatch(tok1->next(), pattern_class); tok1 = Token::findmatch(tok1->next(), pattern_class);
} }
} }
void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const char funcname[]) void CheckClass::CheckConstructors(const Token *tok1, const char funcname[])
{ {
const char * const className = tok1->strAt(1); const char * const className = tok1->strAt(1);
// Check that all member variables are initialized..
bool withClasses = bool(std::string(funcname) == "operator =");
struct VAR *varlist = ClassChecking_GetVarList(tok1, withClasses);
int indentlevel = 0; int indentlevel = 0;
const Token *constructor_token = Tokenizer::FindClassFunction(tok1, className, funcname, indentlevel); const Token *constructor_token = Tokenizer::FindClassFunction(tok1, className, funcname, indentlevel);
std::list<std::string> callstack; std::list<std::string> callstack;
@ -384,6 +394,14 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const
callstack.clear(); callstack.clear();
ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack); ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack);
} }
// Delete the varlist..
while (varlist)
{
struct VAR *nextvar = varlist->next;
delete varlist;
varlist = nextvar;
}
} }

View File

@ -93,10 +93,10 @@ private:
void ClassChecking_VarList_Initialize(const Token *tok1, const Token *ftok, struct VAR *varlist, const char classname[], std::list<std::string> &callstack); void ClassChecking_VarList_Initialize(const Token *tok1, const Token *ftok, struct VAR *varlist, const char classname[], std::list<std::string> &callstack);
void InitVar(struct VAR *varlist, const char varname[]); void InitVar(struct VAR *varlist, const char varname[]);
struct VAR *ClassChecking_GetVarList(const Token *tok1); struct VAR *ClassChecking_GetVarList(const Token *tok1, bool withClasses);
// Check constructors for a specified class // Check constructors for a specified class
void CheckConstructors(const Token *tok1, struct VAR *varlist, const char funcname[]); void CheckConstructors(const Token *tok1, const char funcname[]);
// Reporting errors.. // Reporting errors..
void noConstructorError(const Token *tok, const std::string &classname); void noConstructorError(const Token *tok, const std::string &classname);

View File

@ -355,7 +355,7 @@ private:
"\n" "\n"
"void Fred::operator=(const Fred &f)\n" "void Fred::operator=(const Fred &f)\n"
"{ }"); "{ }");
TODO_ASSERT_EQUALS(std::string("[test.cpp:14] (style) Fred::ints is not modified in operator=\n"), errout.str()); ASSERT_EQUALS(std::string("[test.cpp:13]: (all style) Member variable 'Fred::ints' is not assigned a value in 'Fred::operator='\n"), errout.str());
} }
}; };