Fix #8336 FN stlcstrParam (#4389)

* Fix #7515 New check: Not needed c_str() operation

* Comment

* Fix error messages

* Handle more complex string expressions

* Fix #8336 FN stlcstrParam

* Handle iterators

* Format

* Format

* Parentheses
This commit is contained in:
chrchr-github 2022-08-21 13:04:43 +02:00 committed by GitHub
parent 1202efb438
commit d351a97a0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 9 deletions

View File

@ -1992,7 +1992,8 @@ void CheckStl::string_c_str()
break;
if (tok2 && Token::Match(tok2->tokAt(-4), ". c_str|data ( )")) {
const Variable* var = tok2->tokAt(-5)->variable();
if (var && var->isStlStringType()) {
if (var && (var->isStlStringType() ||
(var->valueType() && var->valueType()->type == ValueType::ITERATOR && isStlStringType(var->valueType()->containerTypeToken)))) {
string_c_strParam(tok, i->second);
} else if (Token::Match(tok2->tokAt(-9), "%name% . str ( )")) { // Check ss.str().c_str() as parameter
const Variable* ssVar = tok2->tokAt(-9)->variable();
@ -2011,10 +2012,11 @@ void CheckStl::string_c_str()
string_c_strConcat(tok);
} else if (printPerformance && Token::simpleMatch(tok, "<<") && tok->astOperand2() && Token::simpleMatch(tok->astOperand2()->astOperand1(), ". c_str ( )")) {
const Token* str = tok->astOperand2()->astOperand1()->astOperand1();
if (Token::Match(str, "(|["))
if (Token::Match(str, "(|[") && !(str->valueType() && str->valueType()->type == ValueType::ITERATOR))
str = str->previous();
if (str && ((str->variable() && str->variable()->isStlStringType()) ||
(str->function() && isStlStringType(str->function()->retDef)))) {
(str->function() && isStlStringType(str->function()->retDef)) ||
(str->valueType() && str->valueType()->type == ValueType::ITERATOR && isStlStringType(str->valueType()->containerTypeToken)))) {
const Token* strm = tok;
while (Token::simpleMatch(strm, "<<"))
strm = strm->astOperand1();

View File

@ -3894,6 +3894,14 @@ private:
"[test.cpp:11]: (performance) Passing the result of c_str() to a function that takes std::string as argument no. 1 is slow and redundant.\n",
errout.str());
check("void f(const std::string& s);\n" // #8336
"void g(const std::vector<std::string>& v) {\n"
" for (std::vector<std::string>::const_iterator it = v.begin(); it != v.end(); ++it)\n"
" f(it->c_str());\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (performance) Passing the result of c_str() to a function that takes std::string as argument no. 1 is slow and redundant.\n",
errout.str());
check("void svgFile(const std::string &content, const std::string &fileName, const double end = 1000., const double start = 0.);\n"
"void Bar(std::string filename) {\n"
" std::string str = \"bar\";\n"
@ -4068,19 +4076,28 @@ private:
"}\n");
ASSERT_EQUALS("", errout.str());
check("struct T { std::string g(); std::string a[1]; }\n" // #7515
check("struct T {\n" // #7515
" std::string g();\n"
" std::string a[1];\n"
" std::vector<std::string> v;\n"
"};\n"
"void f(std::stringstream& strm, const std::string& s, T& t) {\n"
" strm << s.c_str();\n"
" strm << \"abc\" << s.c_str();\n"
" strm << \"abc\" << s.c_str() << \"def\";\n"
" strm << \"abc\" << t.g().c_str() << \"def\";\n"
" strm << t.a[0].c_str();\n"
" strm << t.v.begin()->c_str();\n"
" auto it = t.v.begin()\n"
" strm << it->c_str();\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:4]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:5]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:6]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:7]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n",
ASSERT_EQUALS("[test.cpp:7]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:8]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:9]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:10]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:11]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:12]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n"
"[test.cpp:14]: (performance) Passing the result of c_str() to a stream is slow and redundant.\n",
errout.str());
}