@@ -1139,134 +1139,143 @@ static void followVariableExpressionError(const Token *tok1, const Token *tok2,
11391139 errors->push_back (std::move (item));
11401140}
11411141
1142- SmallVector<ReferenceToken> followAllReferences (const Token* tok,
1143- bool temporary,
1144- bool inconclusive,
1145- ErrorPath errors,
1146- int depth)
1142+ void followAllReferences (const Token* tok,
1143+ SmallVectorBase<ReferenceToken>& refs_result,
1144+ bool temporary,
1145+ bool inconclusive,
1146+ ErrorPath errors,
1147+ int depth)
11471148{
11481149 struct ReferenceTokenLess {
11491150 bool operator ()(const ReferenceToken& x, const ReferenceToken& y) const {
11501151 return x.token < y.token ;
11511152 }
11521153 };
1153- SmallVector<ReferenceToken> refs_result;
11541154 if (!tok)
1155- return refs_result ;
1155+ return ;
11561156 if (depth < 0 ) {
11571157 refs_result.push_back ({tok, std::move (errors)});
1158- return refs_result ;
1158+ return ;
11591159 }
11601160 const Variable *var = tok->variable ();
11611161 if (var && var->declarationId () == tok->varId ()) {
11621162 if (var->nameToken () == tok || isStructuredBindingVariable (var)) {
11631163 refs_result.push_back ({tok, std::move (errors)});
1164- return refs_result ;
1164+ return ;
11651165 } else if (var->isReference () || var->isRValueReference ()) {
11661166 const Token * const varDeclEndToken = var->declEndToken ();
11671167 if (!varDeclEndToken) {
11681168 refs_result.push_back ({tok, std::move (errors)});
1169- return refs_result ;
1169+ return ;
11701170 }
11711171 if (var->isArgument ()) {
11721172 errors.emplace_back (varDeclEndToken, " Passed to reference." );
11731173 refs_result.push_back ({tok, std::move (errors)});
1174- return refs_result ;
1174+ return ;
11751175 } else if (Token::simpleMatch (varDeclEndToken, " =" )) {
11761176 if (astHasToken (varDeclEndToken, tok))
1177- return refs_result ;
1177+ return ;
11781178 errors.emplace_back (varDeclEndToken, " Assigned to reference." );
11791179 const Token *vartok = varDeclEndToken->astOperand2 ();
11801180 if (vartok == tok || (!temporary && isTemporary (true , vartok, nullptr , true ) &&
11811181 (var->isConst () || var->isRValueReference ()))) {
11821182 refs_result.push_back ({tok, std::move (errors)});
1183- return refs_result;
1183+ return ;
1184+ }
1185+ if (vartok) {
1186+ followAllReferences (vartok, refs_result, temporary, inconclusive, std::move (errors), depth - 1 );
1187+ return ;
11841188 }
1185- if (vartok)
1186- return followAllReferences (vartok, temporary, inconclusive, std::move (errors), depth - 1 );
11871189 } else {
11881190 refs_result.push_back ({tok, std::move (errors)});
1189- return refs_result ;
1191+ return ;
11901192 }
11911193 }
11921194 } else if (Token::simpleMatch (tok, " ?" ) && Token::simpleMatch (tok->astOperand2 (), " :" )) {
11931195 std::set<ReferenceToken, ReferenceTokenLess> result;
11941196 const Token* tok2 = tok->astOperand2 ();
11951197
1196- auto refs = followAllReferences (tok2->astOperand1 (), temporary, inconclusive, errors, depth - 1 );
1197- result.insert (refs.begin (), refs.end ());
1198- refs = followAllReferences (tok2->astOperand2 (), temporary, inconclusive, errors, depth - 1 );
1199- result.insert (refs.begin (), refs.end ());
1198+ {
1199+ SmallVector<ReferenceToken> refs;
1200+ followAllReferences (tok2->astOperand1 (), refs, temporary, inconclusive, errors, depth - 1 );
1201+ result.insert (refs.begin (), refs.end ());
1202+ }
1203+ {
1204+ SmallVector<ReferenceToken> refs;
1205+ followAllReferences (tok2->astOperand2 (), refs, temporary, inconclusive, errors, depth - 1 );
1206+ result.insert (refs.begin (), refs.end ());
1207+ }
12001208
12011209 if (!inconclusive && result.size () != 1 ) {
12021210 refs_result.push_back ({tok, std::move (errors)});
1203- return refs_result ;
1211+ return ;
12041212 }
12051213
12061214 if (!result.empty ()) {
12071215 refs_result.insert (refs_result.end (), result.begin (), result.end ());
1208- return refs_result ;
1216+ return ;
12091217 }
12101218
12111219 } else if (Token::Match (tok->previous (), " %name% (" )) {
12121220 const Function *f = tok->previous ()->function ();
12131221 if (f) {
12141222 if (!Function::returnsReference (f)) {
12151223 refs_result.push_back ({tok, std::move (errors)});
1216- return refs_result ;
1224+ return ;
12171225 }
12181226 std::set<ReferenceToken, ReferenceTokenLess> result;
12191227 std::vector<const Token*> returns = Function::findReturns (f);
12201228 for (const Token* returnTok : returns) {
12211229 if (returnTok == tok)
12221230 continue ;
1223- for (const ReferenceToken& rt :
1224- followAllReferences (returnTok, temporary, inconclusive, errors, depth - returns.size ())) {
1231+ SmallVector<ReferenceToken> refs;
1232+ followAllReferences (returnTok, refs, temporary, inconclusive, errors, depth - returns.size ());
1233+ for (const ReferenceToken& rt : refs) {
12251234 const Variable* argvar = rt.token ->variable ();
12261235 if (!argvar) {
12271236 refs_result.push_back ({tok, std::move (errors)});
1228- return refs_result ;
1237+ return ;
12291238 }
12301239 if (argvar->isArgument () && (argvar->isReference () || argvar->isRValueReference ())) {
12311240 const int n = getArgumentPos (argvar, f);
12321241 if (n < 0 ) {
12331242 refs_result.push_back ({tok, std::move (errors)});
1234- return refs_result ;
1243+ return ;
12351244 }
12361245 std::vector<const Token*> args = getArguments (tok->previous ());
12371246 if (n >= args.size ()) {
12381247 refs_result.push_back ({tok, std::move (errors)});
1239- return refs_result ;
1248+ return ;
12401249 }
12411250 const Token* argTok = args[n];
12421251 ErrorPath er = errors;
12431252 er.emplace_back (returnTok, " Return reference." );
12441253 er.emplace_back (tok->previous (), " Called function passing '" + argTok->expressionString () + " '." );
1245- auto refs =
1246- followAllReferences (argTok, temporary, inconclusive, std::move (er), depth - returns.size ());
1247- result.insert (refs .begin (), refs .end ());
1254+ SmallVector<ReferenceToken> refs2;
1255+ followAllReferences (argTok, refs2 , temporary, inconclusive, std::move (er), depth - returns.size ());
1256+ result.insert (refs2 .begin (), refs2 .end ());
12481257 if (!inconclusive && result.size () > 1 ) {
12491258 refs_result.push_back ({tok, std::move (errors)});
1250- return refs_result ;
1259+ return ;
12511260 }
12521261 }
12531262 }
12541263 }
12551264 if (!result.empty ()) {
12561265 refs_result.insert (refs_result.end (), result.begin (), result.end ());
1257- return refs_result ;
1266+ return ;
12581267 }
12591268 }
12601269 }
12611270 refs_result.push_back ({tok, std::move (errors)});
1262- return refs_result;
12631271}
12641272
12651273const Token* followReferences (const Token* tok, ErrorPath* errors)
12661274{
12671275 if (!tok)
12681276 return nullptr ;
1269- auto refs = followAllReferences (tok, true , false );
1277+ SmallVector<ReferenceToken> refs;
1278+ followAllReferences (tok, refs, true , false );
12701279 if (refs.size () == 1 ) {
12711280 if (errors)
12721281 *errors = std::move (refs.front ().errors );
0 commit comments