@@ -105,7 +105,7 @@ void CheckClass::constructors()
105105 // Mark all variables not used
106106 clearAllVar (usage);
107107
108- std::list<std::string > callstack;
108+ std::list<const Function * > callstack;
109109 initializeVarList (*func, callstack, &(*scope), usage);
110110
111111 // Check if any variables are uninitialized
@@ -354,7 +354,7 @@ bool CheckClass::isBaseClassFunc(const Token *tok, const Scope *scope)
354354 return false ;
355355}
356356
357- void CheckClass::initializeVarList (const Function &func, std::list<std::string > &callstack, const Scope *scope, std::vector<Usage> &usage)
357+ void CheckClass::initializeVarList (const Function &func, std::list<const Function * > &callstack, const Scope *scope, std::vector<Usage> &usage)
358358{
359359 bool initList = func.type == Function::eConstructor || func.type == Function::eCopyConstructor;
360360 const Token *ftok = func.arg ->link ()->next ();
@@ -364,8 +364,35 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
364364 // clKalle::clKalle() : var(value) { }
365365 if (initList) {
366366 if (level == 0 && Token::Match (ftok, " %var% (" )) {
367- if (ftok->strAt (2 ) != " )" )
368- initVar (ftok->str (), scope, usage);
367+ if (ftok->str () != func.name ()) {
368+ if (ftok->strAt (2 ) != " )" )
369+ initVar (ftok->str (), scope, usage);
370+ } else { // c++11 delegate constructor
371+ const Function *member = symbolDatabase->findFunctionByNameAndArgsInScope (ftok, scope);
372+ // member function found
373+ if (member) {
374+ // recursive call
375+ // assume that all variables are initialized
376+ if (std::find (callstack.begin (), callstack.end (), member) != callstack.end ()) {
377+ /* * @todo false negative: just bail */
378+ assignAllVar (usage);
379+ return ;
380+ }
381+
382+ // member function has implementation
383+ if (member->hasBody ) {
384+ // initialize variable use list using member function
385+ callstack.push_back (member);
386+ initializeVarList (*member, callstack, scope, usage);
387+ callstack.pop_back ();
388+ }
389+
390+ // there is a called member function, but it has no implementation, so we assume it initializes everything
391+ else {
392+ assignAllVar (usage);
393+ }
394+ }
395+ }
369396 } else if (level == 0 && Token::Match (ftok, " %var% {" ) && ftok->str () != " const" && Token::Match (ftok->next ()->link ()->next (), " ,|{|%type%" )) {
370397 initVar (ftok->str (), scope, usage);
371398 ftok = ftok->linkAt (1 );
@@ -469,29 +496,22 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
469496 // Calling member function?
470497 else if (Token::simpleMatch (ftok, " operator= (" ) &&
471498 ftok->previous ()->str () != " ::" ) {
472- // recursive call / calling overloaded function
473- // assume that all variables are initialized
474- if (std::find (callstack.begin (), callstack.end (), ftok->str ()) != callstack.end ()) {
475- /* * @todo false negative: just bail */
476- assignAllVar (usage);
477- return ;
478- }
479-
480- /* * @todo check function parameters for overloaded function so we check the right one */
481- // check if member function exists
482- std::list<Function>::const_iterator it;
483- for (it = scope->functionList .begin (); it != scope->functionList .end (); ++it) {
484- if (ftok->str () == it->tokenDef ->str () && it->type != Function::eConstructor)
485- break ;
486- }
487-
499+ const Function *member = symbolDatabase->findFunctionByNameAndArgsInScope (ftok, scope);
488500 // member function found
489- if (it != scope->functionList .end ()) {
501+ if (member) {
502+ // recursive call
503+ // assume that all variables are initialized
504+ if (std::find (callstack.begin (), callstack.end (), member) != callstack.end ()) {
505+ /* * @todo false negative: just bail */
506+ assignAllVar (usage);
507+ return ;
508+ }
509+
490510 // member function has implementation
491- if (it ->hasBody ) {
511+ if (member ->hasBody ) {
492512 // initialize variable use list using member function
493- callstack.push_back (ftok-> str () );
494- initializeVarList (*it , callstack, scope, usage);
513+ callstack.push_back (member );
514+ initializeVarList (*member , callstack, scope, usage);
495515 callstack.pop_back ();
496516 }
497517
@@ -517,27 +537,23 @@ void CheckClass::initializeVarList(const Function &func, std::list<std::string>
517537 }
518538 }
519539
520- // recursive call / calling overloaded function
521- // assume that all variables are initialized
522- if (std::find (callstack.begin (), callstack.end (), ftok->str ()) != callstack.end ()) {
523- assignAllVar (usage);
524- return ;
525- }
526-
527540 // check if member function
528- std::list<Function>::const_iterator it;
529- for (it = scope->functionList .begin (); it != scope->functionList .end (); ++it) {
530- if (ftok->str () == it->tokenDef ->str () && it->type != Function::eConstructor)
531- break ;
532- }
541+ const Function *member = symbolDatabase->findFunctionByNameAndArgsInScope (ftok, scope);
533542
534543 // member function found
535- if (it != scope->functionList .end ()) {
544+ if (member && member->type != Function::eConstructor) {
545+ // recursive call
546+ // assume that all variables are initialized
547+ if (std::find (callstack.begin (), callstack.end (), member) != callstack.end ()) {
548+ assignAllVar (usage);
549+ return ;
550+ }
551+
536552 // member function has implementation
537- if (it ->hasBody ) {
553+ if (member ->hasBody ) {
538554 // initialize variable use list using member function
539- callstack.push_back (ftok-> str () );
540- initializeVarList (*it , callstack, scope, usage);
555+ callstack.push_back (member );
556+ initializeVarList (*member , callstack, scope, usage);
541557 callstack.pop_back ();
542558
543559 // Assume that variables that are passed to it are initialized..
0 commit comments