diff --git a/src/checkclass.cpp b/src/checkclass.cpp index 4978ea8e2..b9dbb4cb1 100644 --- a/src/checkclass.cpp +++ b/src/checkclass.cpp @@ -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.. struct VAR *varlist = NULL; @@ -84,7 +84,9 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1) // Is it a variable declaration? else if (Token::Match(next, "%type% %var% ;")) { - if (next->isStandardType()) + if (withClasses) + varname = next->strAt(1); + else if (next->isStandardType()) varname = next->strAt(1); else if (Token::findmatch(_tokenizer->tokens(), ("enum " + next->str()).c_str())) varname = next->strAt(1); @@ -102,6 +104,21 @@ struct CheckClass::VAR *CheckClass::ClassChecking_GetVarList(const Token *tok1) 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 (varname) { @@ -309,7 +326,7 @@ void CheckClass::constructors() if (ErrorLogger::noConstructor(*_settings)) { // 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) { noConstructorError(tok1, classNameToken->str()); @@ -327,31 +344,24 @@ void CheckClass::constructors() continue; } - // Check that all member variables are initialized.. - struct VAR *varlist = ClassChecking_GetVarList(tok1); - // Check constructors - CheckConstructors(tok1, varlist, className[0]); + CheckConstructors(tok1, className[0]); // Check assignment operators - CheckConstructors(tok1, varlist, "operator ="); - - // Delete the varlist.. - while (varlist) - { - struct VAR *nextvar = varlist->next; - delete varlist; - varlist = nextvar; - } + CheckConstructors(tok1, "operator ="); 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); + // Check that all member variables are initialized.. + bool withClasses = bool(std::string(funcname) == "operator ="); + struct VAR *varlist = ClassChecking_GetVarList(tok1, withClasses); + int indentlevel = 0; const Token *constructor_token = Tokenizer::FindClassFunction(tok1, className, funcname, indentlevel); std::list callstack; @@ -384,6 +394,14 @@ void CheckClass::CheckConstructors(const Token *tok1, struct VAR *varlist, const callstack.clear(); ClassChecking_VarList_Initialize(tok1, constructor_token, varlist, className, callstack); } + + // Delete the varlist.. + while (varlist) + { + struct VAR *nextvar = varlist->next; + delete varlist; + varlist = nextvar; + } } diff --git a/src/checkclass.h b/src/checkclass.h index af97e7aec..96ea923fb 100644 --- a/src/checkclass.h +++ b/src/checkclass.h @@ -93,10 +93,10 @@ 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[]); - struct VAR *ClassChecking_GetVarList(const Token *tok1); + struct VAR *ClassChecking_GetVarList(const Token *tok1, bool withClasses); // 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.. void noConstructorError(const Token *tok, const std::string &classname); diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 178893396..035dd367d 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -355,7 +355,7 @@ private: "\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()); } };