Skip to content

Commit 6559527

Browse files
Update checkstl.cpp
1 parent a8bdf5f commit 6559527

1 file changed

Lines changed: 41 additions & 21 deletions

File tree

lib/checkstl.cpp

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1959,29 +1959,53 @@ static bool isLocal(const Token *tok)
19591959
return var && !var->isStatic() && var->isLocal();
19601960
}
19611961

1962+
static bool isc_strCall(const Token* tok)
1963+
{
1964+
if (!Token::simpleMatch(tok, "("))
1965+
return false;
1966+
const Token* dot = tok->astOperand1();
1967+
if (!Token::simpleMatch(dot, "."))
1968+
return false;
1969+
const Token* obj = dot->astOperand1();
1970+
if (!obj || !obj->valueType() || !obj->valueType()->container || !obj->valueType()->container->stdStringLike)
1971+
return false;
1972+
return Token::Match(dot->astOperand2(), "c_str|data ( )");
1973+
}
1974+
19621975
static bool isc_strConcat(const Token* tok)
19631976
{
19641977
if (!Token::simpleMatch(tok, "+"))
19651978
return false;
19661979
const Token* cstr = nullptr;
19671980
for (const Token* op : { tok->astOperand1(), tok->astOperand2() }) {
1968-
if (!Token::simpleMatch(op, "("))
1969-
continue;
1970-
const Token* dot = op->astOperand1();
1971-
if (!Token::simpleMatch(dot, ".") || !dot->astOperand1())
1972-
continue;
1973-
const ValueType* vtObject = dot->astOperand1()->valueType();
1974-
if (!vtObject || !vtObject->container || !vtObject->container->stdStringLike)
1975-
continue;
1976-
if (!Token::Match(dot->astOperand2(), "c_str|data ( )"))
1977-
continue;
1978-
cstr = op;
1979-
break;
1981+
if (isc_strCall(op)) {
1982+
cstr = op;
1983+
break;
1984+
}
19801985
}
19811986
if (!cstr)
19821987
return false;
1983-
const ValueType* vtStr = (cstr == tok->astOperand1() ? tok->astOperand2() : tok->astOperand1())->valueType();
1984-
return vtStr && vtStr->container && vtStr->container->stdStringLike;
1988+
const Token* strTok = (cstr == tok->astOperand1()) ? tok->astOperand2() : tok->astOperand1();
1989+
return strTok->valueType() && strTok->valueType()->container && strTok->valueType()->container->stdStringLike;
1990+
}
1991+
1992+
static bool isc_strAssignment(const Token* tok)
1993+
{
1994+
if (!Token::simpleMatch(tok, "="))
1995+
return false;
1996+
if (!isc_strCall(tok->astOperand2()))
1997+
return false;
1998+
const Token* strTok = tok->astOperand1();
1999+
return strTok && strTok->valueType() && strTok->valueType()->container && strTok->valueType()->container->stdStringLike;
2000+
}
2001+
2002+
static bool isc_strConstructor(const Token* tok)
2003+
{
2004+
if (!Token::Match(tok, "%var% (|{"))
2005+
return false;
2006+
if (!isc_strCall(tok->tokAt(1)->astOperand2()))
2007+
return false;
2008+
return tok->valueType() && tok->valueType()->container && tok->valueType()->container->stdStringLike;
19852009
}
19862010

19872011
namespace {
@@ -2052,16 +2076,14 @@ void CheckStl::string_c_str()
20522076
const Variable* var2 = tok->tokAt(2)->variable();
20532077
if (var->isPointer() && var2 && var2->isStlType(stl_string_stream))
20542078
string_c_strError(tok);
2079+
} else if (printPerformance && isc_strAssignment(tok->tokAt(1))) {
2080+
string_c_strAssignment(tok, tok->variable()->getTypeName());
20552081
} else if (Token::Match(tok->tokAt(2), "%name% (") &&
20562082
Token::Match(tok->linkAt(3), ") . c_str|data ( ) ;") &&
20572083
tok->tokAt(2)->function() && Token::Match(tok->tokAt(2)->function()->retDef, "std :: string|wstring %name%")) {
20582084
const Variable* var = tok->variable();
20592085
if (var->isPointer())
20602086
string_c_strError(tok);
2061-
} else if (printPerformance && tok->tokAt(1)->astOperand2() && Token::Match(tok->tokAt(1)->astOperand2()->tokAt(-3), "%var% . c_str|data ( ) ;")) {
2062-
const Token* vartok = tok->tokAt(1)->astOperand2()->tokAt(-3);
2063-
if ((tok->variable()->isStlStringType() || tok->variable()->isStlStringViewType()) && vartok->variable() && vartok->variable()->isStlStringType())
2064-
string_c_strAssignment(tok, tok->variable()->getTypeName());
20652087
}
20662088
} else if (printPerformance && tok->function() && Token::Match(tok, "%name% ( !!)") && tok->str() != scope.className) {
20672089
const auto range = c_strFuncParam.equal_range(tok->function());
@@ -2093,9 +2115,7 @@ void CheckStl::string_c_str()
20932115
}
20942116
}
20952117
}
2096-
} else if (printPerformance && Token::Match(tok, "%var% (|{ %var% . c_str|data ( ) !!,") &&
2097-
tok->variable() && (tok->variable()->isStlStringType() || tok->variable()->isStlStringViewType()) &&
2098-
tok->tokAt(2)->variable() && tok->tokAt(2)->variable()->isStlStringType()) {
2118+
} else if (printPerformance && isc_strConstructor(tok)) {
20992119
string_c_strConstructor(tok, tok->variable()->getTypeName());
21002120
} else if (printPerformance && isc_strConcat(tok)) {
21012121
string_c_strConcat(tok);

0 commit comments

Comments
 (0)