@@ -916,7 +916,7 @@ bool CheckUninitVar::checkIfForWhileHead(const Token *startparentheses, const Va
916916}
917917
918918/* * recursively check loop, return error token */
919- const Token* CheckUninitVar::checkLoopBodyRecursive (const Token *start, const Variable& var, const Alloc alloc, const std::string &membervar, bool &bailout) const
919+ const Token* CheckUninitVar::checkLoopBodyRecursive (const Token *start, const Variable& var, const Alloc alloc, const std::string &membervar, bool &bailout, bool &alwaysReturns ) const
920920{
921921 assert (start->str () == " {" );
922922
@@ -941,9 +941,10 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
941941 if (!Token::simpleMatch (top->previous (), " for (" ) || !Token::simpleMatch (top->link (), " ) {" ))
942942 continue ;
943943 const Token *bodyStart = top->link ()->next ();
944- const Token *errorToken1 = checkLoopBodyRecursive (bodyStart, var, alloc, membervar, bailout);
944+ const Token *errorToken1 = checkLoopBodyRecursive (bodyStart, var, alloc, membervar, bailout, alwaysReturns );
945945 if (!errorToken)
946946 errorToken = errorToken1;
947+ bailout |= alwaysReturns;
947948 if (bailout)
948949 return nullptr ;
949950 }
@@ -962,11 +963,12 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
962963 return nullptr ;
963964 }
964965
965- const Token *errorToken1 = checkLoopBodyRecursive (tok, var, alloc, membervar, bailout);
966+ bool alwaysReturnsUnused;
967+ const Token *errorToken1 = checkLoopBodyRecursive (tok, var, alloc, membervar, bailout, alwaysReturnsUnused);
966968 tok = tok->link ();
967969 if (Token::simpleMatch (tok, " } else {" )) {
968970 const Token *elseBody = tok->tokAt (2 );
969- const Token *errorToken2 = checkLoopBodyRecursive (elseBody, var, alloc, membervar, bailout);
971+ const Token *errorToken2 = checkLoopBodyRecursive (elseBody, var, alloc, membervar, bailout, alwaysReturnsUnused );
970972 tok = elseBody->link ();
971973 if (errorToken1 && errorToken2)
972974 return errorToken1;
@@ -979,6 +981,23 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
979981 errorToken = errorToken1;
980982 }
981983
984+ if (Token::simpleMatch (tok, " return" )) {
985+ bool returnWithoutVar = true ;
986+ while (tok && !Token::simpleMatch (tok, " ;" )) {
987+ if (tok->isVariable () && tok->variable () == &var) {
988+ returnWithoutVar = false ;
989+ break ;
990+ }
991+ tok = tok->next ();
992+ }
993+ if (returnWithoutVar) {
994+ alwaysReturns = true ;
995+ return nullptr ;
996+ }
997+ }
998+ if (!tok)
999+ break ;
1000+
9821001 if (tok->varId () != var.declarationId ())
9831002 continue ;
9841003
@@ -1068,17 +1087,18 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
10681087bool CheckUninitVar::checkLoopBody (const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors)
10691088{
10701089 bool bailout = false ;
1071- const Token *errorToken = checkLoopBodyRecursive (tok, var, alloc, membervar, bailout);
1090+ bool alwaysReturns = false ;
1091+ const Token *errorToken = checkLoopBodyRecursive (tok, var, alloc, membervar, bailout, alwaysReturns);
10721092
1073- if (!suppressErrors && !bailout && errorToken) {
1093+ if (!suppressErrors && !bailout && !alwaysReturns && errorToken) {
10741094 if (membervar.empty ())
10751095 uninitvarError (errorToken, errorToken->expressionString (), alloc);
10761096 else
10771097 uninitStructMemberError (errorToken, errorToken->expressionString () + " ." + membervar);
10781098 return true ;
10791099 }
10801100
1081- return bailout;
1101+ return bailout || alwaysReturns ;
10821102}
10831103
10841104void CheckUninitVar::checkRhs (const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar)
0 commit comments