Fix #12147 false negative: passedByValue (#5626)

This commit is contained in:
chrchr-github 2023-11-07 22:50:31 +01:00 committed by GitHub
parent bc174c502a
commit cf64ccea22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 20 deletions

View File

@ -2579,8 +2579,8 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
if (indirect == 0 && astIsPointer(tok))
return false;
const Token *ftok = tok->tokAt(2);
if (astIsContainer(tok) && vt && vt->container) {
const Token *ftok = tok2->astParent()->astOperand2();
if (astIsContainer(tok2->astParent()->astOperand1()) && vt && vt->container) {
const Library::Container* c = vt->container;
const Library::Container::Action action = c->getAction(ftok->str());
if (contains({Library::Container::Action::INSERT,

View File

@ -659,12 +659,11 @@ std::vector<CheckClass::Usage> CheckClass::createUsageList(const Scope *scope)
void CheckClass::assignVar(std::vector<Usage> &usageList, nonneg int varid)
{
for (Usage& usage: usageList) {
if (usage.var->declarationId() == varid) {
usage.assign = true;
return;
}
}
auto it = std::find_if(usageList.begin(), usageList.end(), [varid](const Usage& usage) {
return usage.var->declarationId() == varid;
});
if (it != usageList.end())
it->assign = true;
}
void CheckClass::assignVar(std::vector<Usage> &usageList, const Token* vartok)
@ -673,23 +672,21 @@ void CheckClass::assignVar(std::vector<Usage> &usageList, const Token* vartok)
assignVar(usageList, vartok->varId());
return;
}
for (Usage& usage: usageList) {
auto it = std::find_if(usageList.begin(), usageList.end(), [vartok](const Usage& usage) {
// FIXME: This is a workaround when varid is not set for a derived member
if (usage.var->name() == vartok->str()) {
usage.assign = true;
return;
}
}
return usage.var->name() == vartok->str();
});
if (it != usageList.end())
it->assign = true;
}
void CheckClass::initVar(std::vector<Usage> &usageList, nonneg int varid)
{
for (Usage& usage: usageList) {
if (usage.var->declarationId() == varid) {
usage.init = true;
return;
}
}
auto it = std::find_if(usageList.begin(), usageList.end(), [varid](const Usage& usage) {
return usage.var->declarationId() == varid;
});
if (it != usageList.end())
it->init = true;
}
void CheckClass::assignAllVar(std::vector<Usage> &usageList)

View File

@ -2191,6 +2191,25 @@ private:
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct S { std::list<int> l; };\n" // #12147
"class C { public: std::list<int> l; };\n"
"bool f(S s) {\n"
" return s.l.empty();\n"
"}\n"
"bool f(C c) {\n"
" return c.l.empty();\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (performance) Function parameter 's' should be passed by const reference.\n"
"[test.cpp:6]: (performance) Function parameter 'c' should be passed by const reference.\n",
errout.str());
check("struct S { std::list<int> a[1][1]; };\n"
"bool f(S s) {\n"
" return s.a[0][0].empty();\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (performance) Function parameter 's' should be passed by const reference.\n",
errout.str());
Settings settings1 = settingsBuilder().platform(Platform::Type::Win64).build();
check("using ui64 = unsigned __int64;\n"
"ui64 Test(ui64 one, ui64 two) { return one + two; }\n",