class checking: Checking that vectors/lists/strings etc are modified in the assignment function
This commit is contained in:
parent
7e5c32b7f4
commit
534d0e9939
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue