Skip to content

Commit 3836367

Browse files
Fix FN passedByValue with array access, range-based for (#4922)
* Fix FN passedByValue with array access, range-based for * Format * Fix/suppress new warnings
1 parent fc24f76 commit 3836367

7 files changed

Lines changed: 54 additions & 9 deletions

File tree

gui/checkthread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
#include <QSettings>
4646

4747
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
48-
static bool executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output)
48+
static bool executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output) // cppcheck-suppress passedByValue
4949
{
5050
output.clear();
5151

gui/mainwindow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ void MainWindow::checkConfiguration()
11581158
analyzeProject(mProjectFile, false, true);
11591159
}
11601160

1161-
void MainWindow::reAnalyzeSelected(QStringList files)
1161+
void MainWindow::reAnalyzeSelected(const QStringList& files)
11621162
{
11631163
if (files.empty())
11641164
return;

gui/mainwindow.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ private slots:
251251
* @brief Reanalyze selected files
252252
* @param files list of selected files
253253
*/
254-
void reAnalyzeSelected(QStringList files);
254+
void reAnalyzeSelected(const QStringList& files);
255255

256256
/**
257257
* @brief Analyze the project.

lib/checkother.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,6 +1176,14 @@ static int estimateSize(const Type* type, const Settings* settings, const Symbol
11761176
});
11771177
}
11781178

1179+
static bool isConstRangeBasedFor(const Token* tok) {
1180+
if (astIsRangeBasedForDecl(tok)) {
1181+
const Variable* loopVar = tok->astParent()->astOperand1()->variable();
1182+
return loopVar && (!loopVar->isReference() || loopVar->isConst());
1183+
}
1184+
return false;
1185+
}
1186+
11791187
static bool canBeConst(const Variable *var, const Settings* settings)
11801188
{
11811189
if (!var->scope())
@@ -1201,6 +1209,8 @@ static bool canBeConst(const Variable *var, const Settings* settings)
12011209
continue;
12021210

12031211
const Token* parent = tok2->astParent();
1212+
while (Token::simpleMatch(parent, "["))
1213+
parent = parent->astParent();
12041214
if (!parent)
12051215
continue;
12061216
if (Token::simpleMatch(tok2->next(), ";") && tok2->next()->isSplittedVarDeclEq()) {
@@ -1249,9 +1259,12 @@ static bool canBeConst(const Variable *var, const Settings* settings)
12491259
(parent->astOperand2() && settings->library.isFunctionConst(parent->astOperand2())))
12501260
continue;
12511261
else if (parent->isAssignmentOp()) {
1252-
if (parent->astOperand1() == tok2)
1262+
const Token* assignee = parent->astOperand1();
1263+
while (Token::simpleMatch(assignee, "["))
1264+
assignee = assignee->astOperand1();
1265+
if (assignee == tok2)
12531266
return false;
1254-
const Variable* assignedVar = parent->astOperand1() ? parent->astOperand1()->variable() : nullptr;
1267+
const Variable* assignedVar = assignee ? assignee->variable() : nullptr;
12551268
if (assignedVar &&
12561269
!assignedVar->isConst() &&
12571270
assignedVar->isReference() &&
@@ -1263,7 +1276,9 @@ static bool canBeConst(const Variable *var, const Settings* settings)
12631276
continue;
12641277
else
12651278
return false;
1266-
} else
1279+
} else if (isConstRangeBasedFor(tok2))
1280+
continue;
1281+
else
12671282
return false;
12681283
}
12691284

lib/importproject.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ static std::string unescape(const std::string &in)
274274
return out;
275275
}
276276

277-
void ImportProject::FileSettings::parseCommand(std::string command)
277+
void ImportProject::FileSettings::parseCommand(const std::string& command)
278278
{
279279
std::string defs;
280280

lib/importproject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ class CPPCHECKLIB ImportProject {
7878
bool msc;
7979
bool useMfc;
8080

81-
void parseCommand(std::string command);
81+
void parseCommand(const std::string& command);
8282
void setDefines(std::string defs);
8383
void setIncludePaths(const std::string &basepath, const std::list<std::string> &in, std::map<std::string, std::string, cppcheck::stricmp> &variables);
8484
};

test/testother.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,36 @@ class TestOther : public TestFixture {
19931993
"}\n");
19941994
ASSERT_EQUALS("", errout.str());
19951995

1996+
check("int x(int);\n"
1997+
"void f(std::vector<int> v, int& j) {\n"
1998+
" for (int i : v)\n"
1999+
" j = i;\n"
2000+
"}\n"
2001+
"void fn(std::vector<int> v) {\n"
2002+
" for (int& i : v)\n"
2003+
" i = x(i);\n"
2004+
"}\n"
2005+
"void g(std::vector<int> v, int& j) {\n"
2006+
" for (int i = 0; i < v.size(); ++i)\n"
2007+
" j = v[i];\n"
2008+
"}\n"
2009+
"void gn(std::vector<int> v) {\n"
2010+
" for (int i = 0; i < v.size(); ++i)\n"
2011+
" v[i] = x(i);\n"
2012+
"}\n"
2013+
"void h(std::vector<std::vector<int>> v, int& j) {\n"
2014+
" for (int i = 0; i < v.size(); ++i)\n"
2015+
" j = v[i][0];\n"
2016+
"}\n"
2017+
"void hn(std::vector<std::vector<int>> v) {\n"
2018+
" for (int i = 0; i < v.size(); ++i)\n"
2019+
" v[i][0] = x(i);\n"
2020+
"}\n");
2021+
ASSERT_EQUALS("[test.cpp:2]: (performance) Function parameter 'v' should be passed by const reference.\n"
2022+
"[test.cpp:10]: (performance) Function parameter 'v' should be passed by const reference.\n"
2023+
"[test.cpp:18]: (performance) Function parameter 'v' should be passed by const reference.\n",
2024+
errout.str());
2025+
19962026
Settings settings1;
19972027
PLATFORM(settings1.platform, cppcheck::Platform::Type::Win64);
19982028
check("using ui64 = unsigned __int64;\n"
@@ -2194,7 +2224,7 @@ class TestOther : public TestFixture {
21942224
" const int& i = x[0];\n"
21952225
" return i;\n"
21962226
"}");
2197-
ASSERT_EQUALS("", errout.str());
2227+
ASSERT_EQUALS("[test.cpp:1]: (performance) Function parameter 'x' should be passed by const reference.\n", errout.str());
21982228

21992229
check("int f(std::vector<int> x) {\n"
22002230
" static int& i = x[0];\n"

0 commit comments

Comments
 (0)