@@ -1212,121 +1212,101 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
12121212 };
12131213 if (!tok)
12141214 return {};
1215- if (depth < 0 ) {
1216- SmallVector<ReferenceToken> refs_result;
1217- refs_result.emplace_back (ReferenceToken{tok, std::move (errors)});
1218- return refs_result;
1219- }
1220- const Variable *var = tok->variable ();
1221- if (var && var->declarationId () == tok->varId ()) {
1222- if (var->nameToken () == tok || isStructuredBindingVariable (var)) {
1223- SmallVector<ReferenceToken> refs_result;
1224- refs_result.push_back ({tok, std::move (errors)});
1225- return refs_result;
1226- }
1227- if (var->isReference () || var->isRValueReference ()) {
1228- const Token * const varDeclEndToken = var->declEndToken ();
1229- if (!varDeclEndToken) {
1230- SmallVector<ReferenceToken> refs_result;
1231- refs_result.push_back ({tok, std::move (errors)});
1232- return refs_result;
1233- }
1234- if (var->isArgument ()) {
1235- errors.emplace_back (varDeclEndToken, " Passed to reference." );
1236- SmallVector<ReferenceToken> refs_result;
1237- refs_result.push_back ({tok, std::move (errors)});
1238- return refs_result;
1215+ do {
1216+ if (depth < 0 ) {
1217+ break ;
1218+ }
1219+ const Variable *var = tok->variable ();
1220+ if (var && var->declarationId () == tok->varId ()) {
1221+ if (var->nameToken () == tok || isStructuredBindingVariable (var)) {
1222+ break ;
12391223 }
1240- if (Token::simpleMatch (varDeclEndToken, " =" )) {
1241- if (astHasToken (varDeclEndToken, tok))
1242- return {};
1243- errors.emplace_back (varDeclEndToken, " Assigned to reference." );
1244- const Token *vartok = varDeclEndToken->astOperand2 ();
1245- if (vartok == tok || (!temporary && isTemporary (true , vartok, nullptr , true ) &&
1246- (var->isConst () || var->isRValueReference ()))) {
1247- SmallVector<ReferenceToken> refs_result;
1248- refs_result.push_back ({tok, std::move (errors)});
1249- return refs_result;
1224+ if (var->isReference () || var->isRValueReference ()) {
1225+ const Token * const varDeclEndToken = var->declEndToken ();
1226+ if (!varDeclEndToken) {
1227+ break ;
1228+ }
1229+ if (var->isArgument ()) {
1230+ errors.emplace_back (varDeclEndToken, " Passed to reference." );
1231+ break ;
1232+ }
1233+ if (Token::simpleMatch (varDeclEndToken, " =" )) {
1234+ if (astHasToken (varDeclEndToken, tok))
1235+ return {};
1236+ errors.emplace_back (varDeclEndToken, " Assigned to reference." );
1237+ const Token *vartok = varDeclEndToken->astOperand2 ();
1238+ if (vartok == tok || (!temporary && isTemporary (true , vartok, nullptr , true ) &&
1239+ (var->isConst () || var->isRValueReference ()))) {
1240+ break ;
1241+ }
1242+ if (vartok)
1243+ return followAllReferences (vartok, temporary, inconclusive, std::move (errors), depth - 1 );
12501244 }
1251- if (vartok)
1252- return followAllReferences (vartok, temporary, inconclusive, std::move (errors), depth - 1 );
12531245 }
1254- }
1255- } else if (Token::simpleMatch (tok, " ?" ) && Token::simpleMatch (tok->astOperand2 (), " :" )) {
1256- std::set<ReferenceToken, ReferenceTokenLess> result;
1257- const Token* tok2 = tok->astOperand2 ();
1246+ } else if (Token::simpleMatch (tok, " ?" ) && Token::simpleMatch (tok->astOperand2 (), " :" )) {
1247+ std::set<ReferenceToken, ReferenceTokenLess> result;
1248+ const Token* tok2 = tok->astOperand2 ();
12581249
1259- auto refs = followAllReferences (tok2->astOperand1 (), temporary, inconclusive, errors, depth - 1 );
1260- result.insert (refs.cbegin (), refs.cend ());
1261- refs = followAllReferences (tok2->astOperand2 (), temporary, inconclusive, errors, depth - 1 );
1262- result.insert (refs.cbegin (), refs.cend ());
1250+ auto refs = followAllReferences (tok2->astOperand1 (), temporary, inconclusive, errors, depth - 1 );
1251+ result.insert (refs.cbegin (), refs.cend ());
1252+ refs = followAllReferences (tok2->astOperand2 (), temporary, inconclusive, errors, depth - 1 );
1253+ result.insert (refs.cbegin (), refs.cend ());
12631254
1264- if (!inconclusive && result.size () != 1 ) {
1265- SmallVector<ReferenceToken> refs_result;
1266- refs_result.push_back ({tok, std::move (errors)});
1267- return refs_result;
1268- }
1255+ if (!inconclusive && result.size () != 1 ) {
1256+ break ;
1257+ }
12691258
1270- if (!result.empty ()) {
1271- SmallVector<ReferenceToken> refs_result;
1272- refs_result.insert (refs_result.end (), result.cbegin (), result.cend ());
1273- return refs_result;
1274- }
1259+ if (!result.empty ()) {
1260+ SmallVector<ReferenceToken> refs_result;
1261+ refs_result.insert (refs_result.end (), result.cbegin (), result.cend ());
1262+ return refs_result;
1263+ }
12751264
1276- } else if (tok->previous () && tok->previous ()->function () && Token::Match (tok->previous (), " %name% (" )) {
1277- const Function *f = tok->previous ()->function ();
1278- if (!Function::returnsReference (f)) {
1279- SmallVector<ReferenceToken> refs_result;
1280- refs_result.push_back ({tok, std::move (errors)});
1281- return refs_result;
1282- }
1283- std::set<ReferenceToken, ReferenceTokenLess> result;
1284- std::vector<const Token*> returns = Function::findReturns (f);
1285- for (const Token* returnTok : returns) {
1286- if (returnTok == tok)
1287- continue ;
1288- for (const ReferenceToken& rt :
1289- followAllReferences (returnTok, temporary, inconclusive, errors, depth - returns.size ())) {
1290- const Variable* argvar = rt.token ->variable ();
1291- if (!argvar) {
1292- SmallVector<ReferenceToken> refs_result;
1293- refs_result.push_back ({tok, std::move (errors)});
1294- return refs_result;
1295- }
1296- if (argvar->isArgument () && (argvar->isReference () || argvar->isRValueReference ())) {
1297- const int n = getArgumentPos (argvar, f);
1298- if (n < 0 ) {
1299- SmallVector<ReferenceToken> refs_result;
1300- refs_result.push_back ({tok, std::move (errors)});
1301- return refs_result;
1302- }
1303- std::vector<const Token*> args = getArguments (tok->previous ());
1304- if (n >= args.size ()) {
1305- SmallVector<ReferenceToken> refs_result;
1306- refs_result.push_back ({tok, std::move (errors)});
1307- return refs_result;
1265+ } else if (tok->previous () && tok->previous ()->function () && Token::Match (tok->previous (), " %name% (" )) {
1266+ const Function *f = tok->previous ()->function ();
1267+ if (!Function::returnsReference (f)) {
1268+ break ;
1269+ }
1270+ std::set<ReferenceToken, ReferenceTokenLess> result;
1271+ std::vector<const Token*> returns = Function::findReturns (f);
1272+ for (const Token* returnTok : returns) {
1273+ if (returnTok == tok)
1274+ continue ;
1275+ for (const ReferenceToken& rt :
1276+ followAllReferences (returnTok, temporary, inconclusive, errors, depth - returns.size ())) {
1277+ const Variable* argvar = rt.token ->variable ();
1278+ if (!argvar) {
1279+ break ;
13081280 }
1309- const Token* argTok = args[n];
1310- ErrorPath er = errors;
1311- er.emplace_back (returnTok, " Return reference." );
1312- er.emplace_back (tok->previous (), " Called function passing '" + argTok->expressionString () + " '." );
1313- auto refs =
1314- followAllReferences (argTok, temporary, inconclusive, std::move (er), depth - returns.size ());
1315- result.insert (refs.cbegin (), refs.cend ());
1316- if (!inconclusive && result.size () > 1 ) {
1317- SmallVector<ReferenceToken> refs_result;
1318- refs_result.push_back ({tok, std::move (errors)});
1319- return refs_result;
1281+ if (argvar->isArgument () && (argvar->isReference () || argvar->isRValueReference ())) {
1282+ const int n = getArgumentPos (argvar, f);
1283+ if (n < 0 ) {
1284+ break ;
1285+ }
1286+ std::vector<const Token*> args = getArguments (tok->previous ());
1287+ if (n >= args.size ()) {
1288+ break ;
1289+ }
1290+ const Token* argTok = args[n];
1291+ ErrorPath er = errors;
1292+ er.emplace_back (returnTok, " Return reference." );
1293+ er.emplace_back (tok->previous (), " Called function passing '" + argTok->expressionString () + " '." );
1294+ auto refs =
1295+ followAllReferences (argTok, temporary, inconclusive, std::move (er), depth - returns.size ());
1296+ if (!inconclusive && refs.size () > 1 ) {
1297+ break ;
1298+ }
1299+ result.insert (refs.cbegin (), refs.cend ());
13201300 }
13211301 }
13221302 }
1303+ if (!result.empty ()) {
1304+ SmallVector<ReferenceToken> refs_result;
1305+ refs_result.insert (refs_result.end (), result.cbegin (), result.cend ());
1306+ return refs_result;
1307+ }
13231308 }
1324- if (!result.empty ()) {
1325- SmallVector<ReferenceToken> refs_result;
1326- refs_result.insert (refs_result.end (), result.cbegin (), result.cend ());
1327- return refs_result;
1328- }
1329- }
1309+ } while (false );
13301310 SmallVector<ReferenceToken> refs_result;
13311311 refs_result.push_back ({tok, std::move (errors)});
13321312 return refs_result;
0 commit comments