@@ -1959,6 +1959,34 @@ static bool isLocal(const Token *tok)
19591959 return var && !var->isStatic () && var->isLocal ();
19601960}
19611961
1962+ static bool isc_strConcat (const Token* tok)
1963+ {
1964+ if (!Token::simpleMatch (tok, " +" ))
1965+ return false ;
1966+ const Token* cstr = nullptr ;
1967+ 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, " ." ))
1972+ continue ;
1973+ if (!Token::Match (dot->astOperand1 (), " %var%" )) // TODO: function returning string
1974+ continue ;
1975+ const Variable* var = dot->astOperand1 ()->variable ();
1976+ if (!var || !var->isStlStringType ())
1977+ continue ;
1978+ if (!Token::Match (dot->astOperand2 (), " c_str|data ( )" ))
1979+ continue ;
1980+ cstr = op;
1981+ }
1982+ if (!cstr)
1983+ return false ;
1984+ const Token* strTok = (cstr == tok->astOperand1 ()) ? tok->astOperand2 () : tok->astOperand1 ();
1985+ if (strTok->variable () && strTok->variable ()->isStlStringType ())
1986+ return true ;
1987+ return strTok->valueType () && strTok->valueType ()->container && strTok->valueType ()->container ->stdStringLike ;
1988+ }
1989+
19621990namespace {
19631991 const std::set<std::string> stl_string_stream = {
19641992 " istringstream" , " ostringstream" , " stringstream" , " wstringstream"
@@ -2072,9 +2100,7 @@ void CheckStl::string_c_str()
20722100 tok->variable () && (tok->variable ()->isStlStringType () || tok->variable ()->isStlStringViewType ()) &&
20732101 tok->tokAt (2 )->variable () && tok->tokAt (2 )->variable ()->isStlStringType ()) {
20742102 string_c_strConstructor (tok, tok->variable ()->getTypeName ());
2075- } else if (printPerformance && tok->next () && tok->next ()->variable () && tok->next ()->variable ()->isStlStringType () && tok->valueType () && tok->valueType ()->type == ValueType::CONTAINER &&
2076- ((Token::Match (tok->previous (), " %var% + %var% . c_str|data ( )" ) && tok->previous ()->variable () && tok->previous ()->variable ()->isStlStringType ()) ||
2077- (Token::Match (tok->tokAt (-5 ), " %var% . c_str|data ( ) + %var%" ) && tok->tokAt (-5 )->variable () && tok->tokAt (-5 )->variable ()->isStlStringType ()))) {
2103+ else if (printPerformance && isc_strConcat (tok)) {
20782104 string_c_strConcat (tok);
20792105 } else if (printPerformance && Token::simpleMatch (tok, " <<" ) && tok->astOperand2 () && Token::Match (tok->astOperand2 ()->astOperand1 (), " . c_str|data ( )" )) {
20802106 const Token* str = tok->astOperand2 ()->astOperand1 ()->astOperand1 ();
0 commit comments