parent
7618e100b4
commit
bbaa7be901
|
@ -580,7 +580,7 @@ bool CppCheckExecutor::tryLoadLibrary(Library& destination, const std::string& b
|
||||||
/**
|
/**
|
||||||
* Execute a shell command and read the output from it. Returns true if command terminated successfully.
|
* Execute a shell command and read the output from it. Returns true if command terminated successfully.
|
||||||
*/
|
*/
|
||||||
// cppcheck-suppress passedByValue - used as callback so we need to preserve the signature
|
// cppcheck-suppress passedByValueCallback - used as callback so we need to preserve the signature
|
||||||
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
|
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
|
||||||
int CppCheckExecutor::executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output_)
|
int CppCheckExecutor::executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output_)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
|
// NOLINTNEXTLINE(performance-unnecessary-value-param) - used as callback so we need to preserve the signature
|
||||||
static int executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output) // cppcheck-suppress passedByValue
|
static int executeCommand(std::string exe, std::vector<std::string> args, std::string redirect, std::string &output) // cppcheck-suppress passedByValueCallback
|
||||||
{
|
{
|
||||||
output.clear();
|
output.clear();
|
||||||
|
|
||||||
|
|
|
@ -1366,7 +1366,7 @@ void CheckOther::checkPassByReference()
|
||||||
|
|
||||||
const bool isConst = var->isConst();
|
const bool isConst = var->isConst();
|
||||||
if (isConst) {
|
if (isConst) {
|
||||||
passedByValueError(var->nameToken(), var->name(), inconclusive);
|
passedByValueError(var, inconclusive);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1375,18 +1375,26 @@ void CheckOther::checkPassByReference()
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (canBeConst(var, mSettings)) {
|
if (canBeConst(var, mSettings)) {
|
||||||
passedByValueError(var->nameToken(), var->name(), inconclusive);
|
passedByValueError(var, inconclusive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckOther::passedByValueError(const Token *tok, const std::string &parname, bool inconclusive)
|
void CheckOther::passedByValueError(const Variable* var, bool inconclusive)
|
||||||
{
|
{
|
||||||
reportError(tok, Severity::performance, "passedByValue",
|
std::string id = "passedByValue";
|
||||||
"$symbol:" + parname + "\n"
|
std::string msg = "$symbol:" + (var ? var->name() : "") + "\n"
|
||||||
"Function parameter '$symbol' should be passed by const reference.\n"
|
"Function parameter '$symbol' should be passed by const reference.";
|
||||||
"Parameter '$symbol' is passed by value. It could be passed "
|
ErrorPath errorPath;
|
||||||
"as a const reference which is usually faster and recommended in C++.", CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
|
if (var && var->scope() && var->scope()->function && var->scope()->function->functionPointerUsage) {
|
||||||
|
id += "Callback";
|
||||||
|
errorPath.emplace_front(var->scope()->function->functionPointerUsage, "Function pointer used here.");
|
||||||
|
msg += " However it seems that '" + var->scope()->function->name() + "' is a callback function.";
|
||||||
|
}
|
||||||
|
if (var)
|
||||||
|
errorPath.emplace_back(var->nameToken(), msg);
|
||||||
|
msg += "\nParameter '$symbol' is passed by value. It could be passed as a const reference which is usually faster and recommended in C++.";
|
||||||
|
reportError(errorPath, Severity::performance, id.c_str(), msg, CWE398, inconclusive ? Certainty::inconclusive : Certainty::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isUnusedVariable(const Variable *var)
|
static bool isUnusedVariable(const Variable *var)
|
||||||
|
|
|
@ -241,7 +241,7 @@ private:
|
||||||
void clarifyStatementError(const Token* tok);
|
void clarifyStatementError(const Token* tok);
|
||||||
void cstyleCastError(const Token *tok);
|
void cstyleCastError(const Token *tok);
|
||||||
void invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt);
|
void invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive, bool toIsInt);
|
||||||
void passedByValueError(const Token *tok, const std::string &parname, bool inconclusive);
|
void passedByValueError(const Variable* var, bool inconclusive);
|
||||||
void constVariableError(const Variable *var, const Function *function);
|
void constVariableError(const Variable *var, const Function *function);
|
||||||
void constStatementError(const Token *tok, const std::string &type, bool inconclusive);
|
void constStatementError(const Token *tok, const std::string &type, bool inconclusive);
|
||||||
void signedCharArrayIndexError(const Token *tok);
|
void signedCharArrayIndexError(const Token *tok);
|
||||||
|
@ -314,7 +314,7 @@ private:
|
||||||
c.checkComparisonFunctionIsAlwaysTrueOrFalseError(nullptr, "isless","varName",false);
|
c.checkComparisonFunctionIsAlwaysTrueOrFalseError(nullptr, "isless","varName",false);
|
||||||
c.checkCastIntToCharAndBackError(nullptr, "func_name");
|
c.checkCastIntToCharAndBackError(nullptr, "func_name");
|
||||||
c.cstyleCastError(nullptr);
|
c.cstyleCastError(nullptr);
|
||||||
c.passedByValueError(nullptr, "parametername", false);
|
c.passedByValueError(nullptr, false);
|
||||||
c.constVariableError(nullptr, nullptr);
|
c.constVariableError(nullptr, nullptr);
|
||||||
c.constStatementError(nullptr, "type", false);
|
c.constStatementError(nullptr, "type", false);
|
||||||
c.signedCharArrayIndexError(nullptr);
|
c.signedCharArrayIndexError(nullptr);
|
||||||
|
|
|
@ -9916,6 +9916,16 @@ private:
|
||||||
check("std::map<int, int> m;\n" // #10817
|
check("std::map<int, int> m;\n" // #10817
|
||||||
"void f(const decltype(m)::const_iterator i) {}");
|
"void f(const decltype(m)::const_iterator i) {}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("int (*pf) (std::vector<int>) = nullptr;\n" // #12118
|
||||||
|
"int f(std::vector<int> v) {\n"
|
||||||
|
" return v.size();\n"
|
||||||
|
"}\n"
|
||||||
|
"void g() {\n"
|
||||||
|
" pf = f;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:6] -> [test.cpp:2]: (performance) Function parameter 'v' should be passed by const reference. However it seems that 'f' is a callback function.\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkComparisonFunctionIsAlwaysTrueOrFalse() {
|
void checkComparisonFunctionIsAlwaysTrueOrFalse() {
|
||||||
|
|
Loading…
Reference in New Issue