@@ -1244,10 +1244,14 @@ void CheckOther::checkPassByReference()
12441244 const SymbolDatabase * const symbolDatabase = mTokenizer ->getSymbolDatabase ();
12451245
12461246 for (const Variable* var : symbolDatabase->variableList ()) {
1247- if (!var || !var->isArgument () || !var-> isClass () || var->isPointer () || var->isArray () || var->isReference () || var->isEnumType ())
1247+ if (!var || !var->isClass () || var->isPointer () || var->isArray () || var->isReference () || var->isEnumType ())
12481248 continue ;
12491249
1250- if (var->scope () && var->scope ()->function ->arg ->link ()->strAt (-1 ) == " ..." )
1250+ const bool isRangeBasedFor = astIsRangeBasedForDecl (var->nameToken ());
1251+ if (!var->isArgument () && !isRangeBasedFor)
1252+ continue ;
1253+
1254+ if (!isRangeBasedFor && var->scope () && var->scope ()->function ->arg ->link ()->strAt (-1 ) == " ..." )
12511255 continue ; // references could not be used as va_start parameters (#5824)
12521256
12531257 const Token * const varDeclEndToken = var->declEndToken ();
@@ -1275,25 +1279,27 @@ void CheckOther::checkPassByReference()
12751279
12761280 const bool isConst = var->isConst ();
12771281 if (isConst) {
1278- passedByValueError (var, inconclusive);
1282+ passedByValueError (var, inconclusive, isRangeBasedFor );
12791283 continue ;
12801284 }
12811285
12821286 // Check if variable could be const
1283- if (!var->scope () || var->scope ()->function ->isImplicitlyVirtual ())
1287+ if (!isRangeBasedFor && (! var->scope () || var->scope ()->function ->isImplicitlyVirtual () ))
12841288 continue ;
12851289
12861290 if (!isVariableChanged (var, mSettings , mTokenizer ->isCPP ())) {
1287- passedByValueError (var, inconclusive);
1291+ passedByValueError (var, inconclusive, isRangeBasedFor );
12881292 }
12891293 }
12901294}
12911295
1292- void CheckOther::passedByValueError (const Variable* var, bool inconclusive)
1296+ void CheckOther::passedByValueError (const Variable* var, bool inconclusive, bool isRangeBasedFor )
12931297{
1294- std::string id = " passedByValue" ;
1295- std::string msg = " $symbol:" + (var ? var->name () : " " ) + " \n "
1296- " Function parameter '$symbol' should be passed by const reference." ;
1298+ std::string id = isRangeBasedFor ? " iterateByValue" : " passedByValue" ;
1299+ const std::string action = isRangeBasedFor ? " declared as" : " passed by" ;
1300+ const std::string type = isRangeBasedFor ? " Range variable" : " Function parameter" ;
1301+ std::string msg = " $symbol:" + (var ? var->name () : " " ) + " \n " +
1302+ type + " '$symbol' should be " + action + " const reference." ;
12971303 ErrorPath errorPath;
12981304 if (var && var->scope () && var->scope ()->function && var->scope ()->function ->functionPointerUsage ) {
12991305 id += " Callback" ;
@@ -1302,7 +1308,10 @@ void CheckOther::passedByValueError(const Variable* var, bool inconclusive)
13021308 }
13031309 if (var)
13041310 errorPath.emplace_back (var->nameToken (), msg);
1305- msg += " \n Parameter '$symbol' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++." ;
1311+ if (isRangeBasedFor)
1312+ msg += " \n Variable '$symbol' is used to iterate by value. It could be declared as a const reference which is usually faster and recommended in C++." ;
1313+ else
1314+ msg += " \n Parameter '$symbol' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++." ;
13061315 reportError (errorPath, Severity::performance, id.c_str (), msg, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
13071316}
13081317
0 commit comments