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)) if (indirect == 0 && astIsPointer(tok))
return false; return false;
const Token *ftok = tok->tokAt(2); const Token *ftok = tok2->astParent()->astOperand2();
if (astIsContainer(tok) && vt && vt->container) { if (astIsContainer(tok2->astParent()->astOperand1()) && vt && vt->container) {
const Library::Container* c = vt->container; const Library::Container* c = vt->container;
const Library::Container::Action action = c->getAction(ftok->str()); const Library::Container::Action action = c->getAction(ftok->str());
if (contains({Library::Container::Action::INSERT, 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) void CheckClass::assignVar(std::vector<Usage> &usageList, nonneg int varid)
{ {
for (Usage& usage: usageList) { auto it = std::find_if(usageList.begin(), usageList.end(), [varid](const Usage& usage) {
if (usage.var->declarationId() == varid) { return usage.var->declarationId() == varid;
usage.assign = true; });
return; if (it != usageList.end())
} it->assign = true;
}
} }
void CheckClass::assignVar(std::vector<Usage> &usageList, const Token* vartok) 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()); assignVar(usageList, vartok->varId());
return; 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 // FIXME: This is a workaround when varid is not set for a derived member
if (usage.var->name() == vartok->str()) { return usage.var->name() == vartok->str();
usage.assign = true; });
return; if (it != usageList.end())
} it->assign = true;
}
} }
void CheckClass::initVar(std::vector<Usage> &usageList, nonneg int varid) void CheckClass::initVar(std::vector<Usage> &usageList, nonneg int varid)
{ {
for (Usage& usage: usageList) { auto it = std::find_if(usageList.begin(), usageList.end(), [varid](const Usage& usage) {
if (usage.var->declarationId() == varid) { return usage.var->declarationId() == varid;
usage.init = true; });
return; if (it != usageList.end())
} it->init = true;
}
} }
void CheckClass::assignAllVar(std::vector<Usage> &usageList) void CheckClass::assignAllVar(std::vector<Usage> &usageList)

View File

@ -2191,6 +2191,25 @@ private:
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); 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(); Settings settings1 = settingsBuilder().platform(Platform::Type::Win64).build();
check("using ui64 = unsigned __int64;\n" check("using ui64 = unsigned __int64;\n"
"ui64 Test(ui64 one, ui64 two) { return one + two; }\n", "ui64 Test(ui64 one, ui64 two) { return one + two; }\n",