@@ -1210,123 +1210,106 @@ SmallVector<ReferenceToken> followAllReferences(const Token* tok,
1210
1210
return x.token < y.token ;
1211
1211
}
1212
1212
};
1213
+
1213
1214
if (!tok)
1214
1215
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 ;
1239
1225
}
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 );
1250
1246
}
1251
- if (vartok)
1252
- return followAllReferences (vartok, temporary, inconclusive, std::move (errors), depth - 1 );
1253
1247
}
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 ();
1258
1251
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 ());
1263
1256
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
+ }
1269
1260
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
+ }
1275
1266
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 ;
1308
1282
}
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 ());
1320
1302
}
1321
1303
}
1322
1304
}
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
+ }
1323
1310
}
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
+
1330
1313
SmallVector<ReferenceToken> refs_result;
1331
1314
refs_result.push_back ({tok, std::move (errors)});
1332
1315
return refs_result;
0 commit comments