@@ -1227,104 +1227,6 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
12271227 });
12281228}
12291229
1230- static bool isConstRangeBasedFor (const Token* tok) {
1231- if (astIsRangeBasedForDecl (tok)) {
1232- const Variable* loopVar = tok->astParent ()->astOperand1 ()->variable ();
1233- return loopVar && (!loopVar->isReference () || loopVar->isConst ());
1234- }
1235- return false ;
1236- }
1237-
1238- static bool canBeConst (const Variable *var, const Settings* settings)
1239- {
1240- if (!var->scope ())
1241- return false ;
1242- {
1243- // check initializer list. If variable is moved from it can't be const.
1244- const Function* func_scope = var->scope ()->function ;
1245- if (func_scope && func_scope->type == Function::Type::eConstructor) {
1246- // could be initialized in initializer list
1247- const Token* init = func_scope->arg ->link ()->next ();
1248- if (init->str () == " noexcept" ) {
1249- init = init->next ();
1250- if (init->link ())
1251- init = init->link ()->next ();
1252- }
1253- if (init->str () == " :" ) {
1254- for (const Token* tok2 = func_scope->arg ->link ()->next ()->next (); tok2 != var->scope ()->bodyStart ; tok2 = tok2->next ()) {
1255- if (tok2->varId () != var->declarationId ())
1256- continue ;
1257- const Token* parent = tok2->astParent ();
1258- if (parent && Token::simpleMatch (parent->previous (), " move (" ))
1259- return false ;
1260- }
1261- }
1262- }
1263- }
1264- for (const Token* tok2 = var->scope ()->bodyStart ; tok2 != var->scope ()->bodyEnd ; tok2 = tok2->next ()) {
1265- if (tok2->varId () != var->declarationId ())
1266- continue ;
1267-
1268- const Token* parent = tok2->astParent ();
1269- while (Token::simpleMatch (parent, " [" ))
1270- parent = parent->astParent ();
1271- if (!parent)
1272- continue ;
1273- if (Token::simpleMatch (tok2->next (), " ;" ) && tok2->next ()->isSplittedVarDeclEq ()) {
1274- tok2 = tok2->tokAt (2 );
1275- tok2 = Token::findsimplematch (tok2, " ;" );
1276- continue ;
1277- }
1278- if (parent->str () == " <<" || isLikelyStreamRead (true , parent)) {
1279- if (parent->str () == " <<" && parent->astOperand1 () == tok2)
1280- return false ;
1281- if (parent->str () == " >>" && parent->astOperand2 () == tok2)
1282- return false ;
1283- } else if (parent->str () == " ," || parent->str () == " (" ) { // function argument
1284- int argNr = -1 ;
1285- const Token* functionTok = getTokenArgumentFunction (tok2, argNr);
1286- if (!functionTok)
1287- return false ;
1288- const Function* tokFunction = functionTok->function ();
1289- if (tokFunction) {
1290- const Variable* argVar = tokFunction->getArgumentVar (argNr);
1291- if (!argVar || (!argVar->isConst () && argVar->isReference ()))
1292- return false ;
1293- }
1294- else if (!settings->library .isFunctionConst (functionTok))
1295- return false ;
1296- } else if (parent->isUnaryOp (" &" )) {
1297- // TODO: check how pointer is used
1298- return false ;
1299- } else if (parent->isConstOp () ||
1300- (parent->astOperand2 () && settings->library .isFunctionConst (parent->astOperand2 ())))
1301- continue ;
1302- else if (parent->isAssignmentOp ()) {
1303- const Token* assignee = parent->astOperand1 ();
1304- while (Token::simpleMatch (assignee, " [" ))
1305- assignee = assignee->astOperand1 ();
1306- if (assignee == tok2)
1307- return false ;
1308- const Variable* assignedVar = assignee ? assignee->variable () : nullptr ;
1309- if (assignedVar &&
1310- !assignedVar->isConst () &&
1311- assignedVar->isReference () &&
1312- assignedVar->nameToken () == parent->astOperand1 ())
1313- return false ;
1314- } else if (Token::Match (tok2, " %var% . %name% (" )) {
1315- const Function* func = tok2->tokAt (2 )->function ();
1316- if (func && (func->isConst () || func->isStatic ()))
1317- continue ;
1318- return false ;
1319- } else if (isConstRangeBasedFor (tok2))
1320- continue ;
1321- else
1322- return false ;
1323- }
1324-
1325- return true ;
1326- }
1327-
13281230void CheckOther::checkPassByReference ()
13291231{
13301232 if (!mSettings ->severity .isEnabled (Severity::performance) || mTokenizer ->isC ())
@@ -1374,7 +1276,7 @@ void CheckOther::checkPassByReference()
13741276 if (!var->scope () || var->scope ()->function ->isImplicitlyVirtual ())
13751277 continue ;
13761278
1377- if (canBeConst (var, mSettings )) {
1279+ if (! isVariableChanged (var, mSettings , mTokenizer -> isCPP () )) {
13781280 passedByValueError (var, inconclusive);
13791281 }
13801282 }
@@ -2939,7 +2841,9 @@ void CheckOther::checkRedundantCopy()
29392841 const SymbolDatabase *symbolDatabase = mTokenizer ->getSymbolDatabase ();
29402842
29412843 for (const Variable* var : symbolDatabase->variableList ()) {
2942- if (!var || var->isReference () || (!var->isConst () && !canBeConst (var, mSettings )) || var->isPointer () || (!var->type () && !var->isStlType ())) // bailout if var is of standard type, if it is a pointer or non-const
2844+ if (!var || var->isReference () || var->isPointer () ||
2845+ (!var->type () && !var->isStlType ()) || // bailout if var is of standard type, if it is a pointer or non-const
2846+ (!var->isConst () && isVariableChanged (var, mSettings , mTokenizer ->isCPP ())))
29432847 continue ;
29442848
29452849 const Token* startTok = var->nameToken ();
0 commit comments