MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / string_c_str

Method string_c_str

lib/checkstl.cpp:2026–2220  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2024}
2025
2026void CheckStlImpl::string_c_str()
2027{
2028 const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive);
2029 const bool printPerformance = mSettings.severity.isEnabled(Severity::performance);
2030
2031 const SymbolDatabase* symbolDatabase = mTokenizer->getSymbolDatabase();
2032
2033 logChecker("CheckStl::string_c_str");
2034
2035 // Find all functions that take std::string as argument
2036 struct StrArg {
2037 nonneg int n;
2038 std::string argtype;
2039 };
2040 std::multimap<const Function*, StrArg> c_strFuncParam;
2041 if (printPerformance) {
2042 for (const Scope &scope : symbolDatabase->scopeList) {
2043 for (const Function &func : scope.functionList) {
2044 nonneg int numpar = 0;
2045 for (const Variable &var : func.argumentList) {
2046 numpar++;
2047 if ((var.isStlStringType() || var.isStlStringViewType()) && (!var.isReference() || var.isConst()))
2048 c_strFuncParam.emplace(&func, StrArg{ numpar, var.getTypeName() });
2049 }
2050 }
2051 }
2052 }
2053
2054 auto isString = [](const Token* str) -> bool {
2055 while (Token::Match(str, "::|."))
2056 str = str->astOperand2();
2057 if (Token::Match(str, "(|[") && !(str->valueType() && str->valueType()->type == ValueType::ITERATOR))
2058 str = str->previous();
2059 return str && ((str->variable() && str->variable()->isStlStringType()) || // variable
2060 (str->function() && isStlStringType(str->function()->retDef)) || // function returning string
2061 (str->valueType() && str->valueType()->type == ValueType::ITERATOR && isStlStringType(str->valueType()->containerTypeToken))); // iterator pointing to string
2062 };
2063
2064 // Try to detect common problems when using string::c_str()
2065 for (const Scope &scope : symbolDatabase->scopeList) {
2066 if (scope.type != ScopeType::eFunction || !scope.function)
2067 continue;
2068
2069 enum : std::uint8_t {charPtr, stdString, stdStringConstRef, Other} returnType = Other;
2070 if (Token::Match(scope.function->tokenDef->tokAt(-2), "char|wchar_t *"))
2071 returnType = charPtr;
2072 else if (Token::Match(scope.function->tokenDef->tokAt(-5), "const std :: string|wstring &"))
2073 returnType = stdStringConstRef;
2074 else if (Token::Match(scope.function->tokenDef->tokAt(-3), "std :: string|wstring !!&"))
2075 returnType = stdString;
2076
2077 for (const Token *tok = scope.bodyStart; tok && tok != scope.bodyEnd; tok = tok->next()) {
2078 // Invalid usage..
2079 if (Token::Match(tok, "throw %var% . c_str|data ( ) ;") && isLocal(tok->next()) &&
2080 tok->next()->variable() && tok->next()->variable()->isStlStringType()) {
2081 string_c_strThrowError(tok);
2082 } else if (tok->variable() && tok->strAt(1) == "=") {
2083 if (Token::Match(tok->tokAt(2), "%var% . str ( ) . c_str|data ( ) ;")) {

Callers 1

runChecksMethod · 0.80

Calls 15

isc_strAssignmentFunction · 0.85
isc_strConstructorFunction · 0.85
isc_strConcatFunction · 0.85
isStlStringViewTypeMethod · 0.80
isConstMethod · 0.80
getTypeNameMethod · 0.80
astOperand2Method · 0.80
variableMethod · 0.80
nextMethod · 0.80
linkAtMethod · 0.80
astOperand1Method · 0.80
isSmartPointerMethod · 0.80

Tested by

no test coverage detected