@@ -1210,123 +1210,106 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
12101210 return x.token < y.token ;
12111211 }
12121212 };
1213+
12131214 if (!tok)
12141215 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;
1216+
1217+ do {
1218+ if (depth < 0 ) {
1219+ break ;
1220+ }
1221+ const Variable *var = tok->variable ();
1222+ if (var && var->declarationId () == tok->varId ()) {
1223+ if (var->nameToken () == tok || isStructuredBindingVariable (var)) {
1224+ break ;
12391225 }
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;
1226+ if (var->isReference () || var->isRValueReference ()) {
1227+ const Token * const varDeclEndToken = var->declEndToken ();
1228+ if (!varDeclEndToken) {
1229+ break ;
1230+ }
1231+ if (var->isArgument ()) {
1232+ errors.emplace_back (varDeclEndToken, " Passed to reference." );
1233+ break ;
1234+ }
1235+ if (Token::simpleMatch (varDeclEndToken, " =" )) {
1236+ if (astHasToken (varDeclEndToken, tok))
1237+ return {};
1238+ errors.emplace_back (varDeclEndToken, " Assigned to reference." );
1239+ const Token *vartok = varDeclEndToken->astOperand2 ();
1240+ if (vartok == tok || (!temporary && isTemporary (true , vartok, nullptr , true ) &&
1241+ (var->isConst () || var->isRValueReference ()))) {
1242+ break ;
1243+ }
1244+ if (vartok)
1245+ return followAllReferences (vartok, temporary, inconclusive, std::move (errors), depth - 1 );
12501246 }
1251- if (vartok)
1252- return followAllReferences (vartok, temporary, inconclusive, std::move (errors), depth - 1 );
12531247 }
1254- }
1255- } else if (Token::simpleMatch (tok, " ?" ) && Token::simpleMatch (tok->astOperand2 (), " :" )) {
1256- std::set<ReferenceToken, ReferenceTokenLess> result;
1257- const Token* tok2 = tok->astOperand2 ();
1248+ } else if (Token::simpleMatch (tok, " ?" ) && Token::simpleMatch (tok->astOperand2 (), " :" )) {
1249+ std::set<ReferenceToken, ReferenceTokenLess> result;
1250+ const Token* tok2 = tok->astOperand2 ();
12581251
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 ());
1252+ auto refs = followAllReferences (tok2->astOperand1 (), temporary, inconclusive, errors, depth - 1 );
1253+ result.insert (refs.cbegin (), refs.cend ());
1254+ refs = followAllReferences (tok2->astOperand2 (), temporary, inconclusive, errors, depth - 1 );
1255+ result.insert (refs.cbegin (), refs.cend ());
12631256
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- }
1257+ if (!inconclusive && result.size () != 1 ) {
1258+ break ;
1259+ }
12691260
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- }
1261+ if (!result.empty ()) {
1262+ SmallVector<ReferenceToken> refs_result;
1263+ refs_result.insert (refs_result.end (), result.cbegin (), result.cend ());
1264+ return refs_result;
1265+ }
12751266
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;
1267+ } else if (tok->previous () && tok->previous ()->function () && Token::Match (tok->previous (), " %name% (" )) {
1268+ const Function *f = tok->previous ()->function ();
1269+ if (!Function::returnsReference (f)) {
1270+ break ;
1271+ }
1272+ std::set<ReferenceToken, ReferenceTokenLess> result;
1273+ std::vector<const Token*> returns = Function::findReturns (f);
1274+ for (const Token* returnTok : returns) {
1275+ if (returnTok == tok)
1276+ continue ;
1277+ for (const ReferenceToken& rt :
1278+ followAllReferences (returnTok, temporary, inconclusive, errors, depth - returns.size ())) {
1279+ const Variable* argvar = rt.token ->variable ();
1280+ if (!argvar) {
1281+ break ;
13081282 }
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;
1283+ if (argvar->isArgument () && (argvar->isReference () || argvar->isRValueReference ())) {
1284+ const int n = getArgumentPos (argvar, f);
1285+ if (n < 0 ) {
1286+ break ;
1287+ }
1288+ std::vector<const Token*> args = getArguments (tok->previous ());
1289+ if (n >= args.size ()) {
1290+ break ;
1291+ }
1292+ const Token* argTok = args[n];
1293+ ErrorPath er = errors;
1294+ er.emplace_back (returnTok, " Return reference." );
1295+ er.emplace_back (tok->previous (), " Called function passing '" + argTok->expressionString () + " '." );
1296+ auto refs =
1297+ followAllReferences (argTok, temporary, inconclusive, std::move (er), depth - returns.size ());
1298+ if (!inconclusive && refs.size () > 1 ) {
1299+ break ;
1300+ }
1301+ result.insert (refs.cbegin (), refs.cend ());
13201302 }
13211303 }
13221304 }
1305+ if (!result.empty ()) {
1306+ SmallVector<ReferenceToken> refs_result;
1307+ refs_result.insert (refs_result.end (), result.cbegin (), result.cend ());
1308+ return refs_result;
1309+ }
13231310 }
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- }
1311+ } while (false );
1312+
13301313 SmallVector<ReferenceToken> refs_result;
13311314 refs_result.push_back ({tok, std::move (errors)});
13321315 return refs_result;
0 commit comments