@@ -916,7 +916,7 @@ bool CheckUninitVar::checkIfForWhileHead(const Token *startparentheses, const Va
916
916
}
917
917
918
918
/* * 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
920
920
{
921
921
assert (start->str () == " {" );
922
922
@@ -941,9 +941,10 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
941
941
if (!Token::simpleMatch (top->previous (), " for (" ) || !Token::simpleMatch (top->link (), " ) {" ))
942
942
continue ;
943
943
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 );
945
945
if (!errorToken)
946
946
errorToken = errorToken1;
947
+ bailout |= alwaysReturns;
947
948
if (bailout)
948
949
return nullptr ;
949
950
}
@@ -962,11 +963,12 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
962
963
return nullptr ;
963
964
}
964
965
965
- const Token *errorToken1 = checkLoopBodyRecursive (tok, var, alloc, membervar, bailout);
966
+ bool alwaysReturnsUnused;
967
+ const Token *errorToken1 = checkLoopBodyRecursive (tok, var, alloc, membervar, bailout, alwaysReturnsUnused);
966
968
tok = tok->link ();
967
969
if (Token::simpleMatch (tok, " } else {" )) {
968
970
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 );
970
972
tok = elseBody->link ();
971
973
if (errorToken1 && errorToken2)
972
974
return errorToken1;
@@ -979,6 +981,23 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
979
981
errorToken = errorToken1;
980
982
}
981
983
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
+
982
1001
if (tok->varId () != var.declarationId ())
983
1002
continue ;
984
1003
@@ -1068,17 +1087,18 @@ const Token* CheckUninitVar::checkLoopBodyRecursive(const Token *start, const Va
1068
1087
bool CheckUninitVar::checkLoopBody (const Token *tok, const Variable& var, const Alloc alloc, const std::string &membervar, const bool suppressErrors)
1069
1088
{
1070
1089
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);
1072
1092
1073
- if (!suppressErrors && !bailout && errorToken) {
1093
+ if (!suppressErrors && !bailout && !alwaysReturns && errorToken) {
1074
1094
if (membervar.empty ())
1075
1095
uninitvarError (errorToken, errorToken->expressionString (), alloc);
1076
1096
else
1077
1097
uninitStructMemberError (errorToken, errorToken->expressionString () + " ." + membervar);
1078
1098
return true ;
1079
1099
}
1080
1100
1081
- return bailout;
1101
+ return bailout || alwaysReturns ;
1082
1102
}
1083
1103
1084
1104
void CheckUninitVar::checkRhs (const Token *tok, const Variable &var, Alloc alloc, nonneg int number_of_if, const std::string &membervar)
0 commit comments