* Fix #11547 FN stlcstrParam with std::string_view * Add suppression * Use emplace() * Fix #11547 FN stlcstrConstructor, stlcstrAssignment with std::string_view
This commit is contained in:
parent
7696bd1357
commit
0ecf101fe3
|
@ -1959,8 +1959,8 @@ void CheckStl::string_c_str()
|
||||||
string_c_strError(tok);
|
string_c_strError(tok);
|
||||||
} else if (printPerformance && tok->tokAt(1)->astOperand2() && Token::Match(tok->tokAt(1)->astOperand2()->tokAt(-3), "%var% . c_str|data ( ) ;")) {
|
} else if (printPerformance && tok->tokAt(1)->astOperand2() && Token::Match(tok->tokAt(1)->astOperand2()->tokAt(-3), "%var% . c_str|data ( ) ;")) {
|
||||||
const Token* vartok = tok->tokAt(1)->astOperand2()->tokAt(-3);
|
const Token* vartok = tok->tokAt(1)->astOperand2()->tokAt(-3);
|
||||||
if (tok->variable()->isStlStringType() && vartok->variable() && vartok->variable()->isStlStringType())
|
if ((tok->variable()->isStlStringType() || tok->variable()->isStlStringViewType()) && vartok->variable() && vartok->variable()->isStlStringType())
|
||||||
string_c_strAssignment(tok);
|
string_c_strAssignment(tok, tok->variable()->getTypeName());
|
||||||
}
|
}
|
||||||
} else if (printPerformance && tok->function() && Token::Match(tok, "%name% ( !!)") && tok->str() != scope.className) {
|
} else if (printPerformance && tok->function() && Token::Match(tok, "%name% ( !!)") && tok->str() != scope.className) {
|
||||||
const auto range = c_strFuncParam.equal_range(tok->function());
|
const auto range = c_strFuncParam.equal_range(tok->function());
|
||||||
|
@ -1993,8 +1993,9 @@ void CheckStl::string_c_str()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (printPerformance && Token::Match(tok, "%var% (|{ %var% . c_str|data ( )") &&
|
} else if (printPerformance && Token::Match(tok, "%var% (|{ %var% . c_str|data ( )") &&
|
||||||
tok->variable() && tok->variable()->isStlStringType() && tok->tokAt(2)->variable() && tok->tokAt(2)->variable()->isStlStringType()) {
|
tok->variable() && (tok->variable()->isStlStringType() || tok->variable()->isStlStringViewType()) &&
|
||||||
string_c_strConstructor(tok);
|
tok->tokAt(2)->variable() && tok->tokAt(2)->variable()->isStlStringType()) {
|
||||||
|
string_c_strConstructor(tok, tok->variable()->getTypeName());
|
||||||
} else if (printPerformance && tok->next() && tok->next()->variable() && tok->next()->variable()->isStlStringType() && tok->valueType() && tok->valueType()->type == ValueType::CONTAINER &&
|
} else if (printPerformance && tok->next() && tok->next()->variable() && tok->next()->variable()->isStlStringType() && tok->valueType() && tok->valueType()->type == ValueType::CONTAINER &&
|
||||||
((Token::Match(tok->previous(), "%var% + %var% . c_str|data ( )") && tok->previous()->variable() && tok->previous()->variable()->isStlStringType()) ||
|
((Token::Match(tok->previous(), "%var% + %var% . c_str|data ( )") && tok->previous()->variable() && tok->previous()->variable()->isStlStringType()) ||
|
||||||
(Token::Match(tok->tokAt(-5), "%var% . c_str|data ( ) + %var%") && tok->tokAt(-5)->variable() && tok->tokAt(-5)->variable()->isStlStringType()))) {
|
(Token::Match(tok->tokAt(-5), "%var% . c_str|data ( ) + %var%") && tok->tokAt(-5)->variable() && tok->tokAt(-5)->variable()->isStlStringType()))) {
|
||||||
|
@ -2115,17 +2116,17 @@ void CheckStl::string_c_strParam(const Token* tok, nonneg int number, const std:
|
||||||
reportError(tok, Severity::performance, "stlcstrParam", oss.str(), CWE704, Certainty::normal);
|
reportError(tok, Severity::performance, "stlcstrParam", oss.str(), CWE704, Certainty::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckStl::string_c_strConstructor(const Token* tok)
|
void CheckStl::string_c_strConstructor(const Token* tok, const std::string& argtype)
|
||||||
{
|
{
|
||||||
std::string msg = "Constructing a std::string from the result of c_str() is slow and redundant.\n"
|
std::string msg = "Constructing a " + argtype + " from the result of c_str() is slow and redundant.\n"
|
||||||
"Constructing a std::string from const char* requires a call to strlen(). Solve that by directly passing the string.";
|
"Constructing a " + argtype + " from const char* requires a call to strlen(). Solve that by directly passing the string.";
|
||||||
reportError(tok, Severity::performance, "stlcstrConstructor", msg, CWE704, Certainty::normal);
|
reportError(tok, Severity::performance, "stlcstrConstructor", msg, CWE704, Certainty::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckStl::string_c_strAssignment(const Token* tok)
|
void CheckStl::string_c_strAssignment(const Token* tok, const std::string& argtype)
|
||||||
{
|
{
|
||||||
std::string msg = "Assigning the result of c_str() to a std::string is slow and redundant.\n"
|
std::string msg = "Assigning the result of c_str() to a " + argtype + " is slow and redundant.\n"
|
||||||
"Assigning a const char* to a std::string requires a call to strlen(). Solve that by directly assigning the string.";
|
"Assigning a const char* to a " + argtype + " requires a call to strlen(). Solve that by directly assigning the string.";
|
||||||
reportError(tok, Severity::performance, "stlcstrAssignment", msg, CWE704, Certainty::normal);
|
reportError(tok, Severity::performance, "stlcstrAssignment", msg, CWE704, Certainty::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,8 +193,8 @@ private:
|
||||||
void string_c_strError(const Token* tok);
|
void string_c_strError(const Token* tok);
|
||||||
void string_c_strReturn(const Token* tok);
|
void string_c_strReturn(const Token* tok);
|
||||||
void string_c_strParam(const Token* tok, nonneg int number, const std::string& argtype = "std::string");
|
void string_c_strParam(const Token* tok, nonneg int number, const std::string& argtype = "std::string");
|
||||||
void string_c_strConstructor(const Token* tok);
|
void string_c_strConstructor(const Token* tok, const std::string& argtype = "std::string");
|
||||||
void string_c_strAssignment(const Token* tok);
|
void string_c_strAssignment(const Token* tok, const std::string& argtype = "std::string");
|
||||||
void string_c_strConcat(const Token* tok);
|
void string_c_strConcat(const Token* tok);
|
||||||
void string_c_strStream(const Token* tok);
|
void string_c_strStream(const Token* tok);
|
||||||
|
|
||||||
|
|
|
@ -4202,6 +4202,18 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (performance) Passing the result of c_str() to a function that takes std::string_view as argument no. 1 is slow and redundant.\n",
|
ASSERT_EQUALS("[test.cpp:3]: (performance) Passing the result of c_str() to a function that takes std::string_view as argument no. 1 is slow and redundant.\n",
|
||||||
errout.str());
|
errout.str());
|
||||||
|
|
||||||
|
check("std::string_view f(const std::string& s) {\n"
|
||||||
|
" std::string_view sv = s.c_str();\n"
|
||||||
|
" return sv;\n"
|
||||||
|
"}\n"
|
||||||
|
"std::string_view g(const std::string& s) {\n"
|
||||||
|
" std::string_view sv{ s.c_str() };\n"
|
||||||
|
" return sv;\n"
|
||||||
|
"}\n");
|
||||||
|
ASSERT_EQUALS("[test.cpp:2]: (performance) Assigning the result of c_str() to a std::string_view is slow and redundant.\n"
|
||||||
|
"[test.cpp:6]: (performance) Constructing a std::string_view from the result of c_str() is slow and redundant.\n",
|
||||||
|
errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void uselessCalls() {
|
void uselessCalls() {
|
||||||
|
|
Loading…
Reference in New Issue