diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 6a6a49c0c..71ca69f4b 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -169,17 +169,15 @@ std::string astCanonicalType(const Token *expr) { if (!expr) return ""; - if (expr->variable()) { - const Variable *var = expr->variable(); + std::pair decl = Token::typeDecl(expr); + if (decl.first && decl.second) { std::string ret; - for (const Token *type = var->typeStartToken(); Token::Match(type,"%name%|::") && type != var->nameToken(); type = type->next()) { + for (const Token *type = decl.first; Token::Match(type,"%name%|::") && type != decl.second; type = type->next()) { if (!Token::Match(type, "const|static")) ret += type->str(); } return ret; - } - // TODO: handle expressions return ""; } diff --git a/lib/errorlogger.cpp b/lib/errorlogger.cpp index 081c9effb..6ef4b28d4 100644 --- a/lib/errorlogger.cpp +++ b/lib/errorlogger.cpp @@ -682,6 +682,9 @@ std::string ErrorLogger::toxml(const std::string &str) case '\"': xml << """; break; + case '\'': + xml << "'"; + break; case '\0': xml << "\\0"; break; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 1637e6656..64d7d8575 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -5707,7 +5707,7 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V } else valuetype->type = ValueType::Type::RECORD; bool par = false; - while (Token::Match(type, "%name%|*|&|::|(") && !Token::Match(type, "typename|template") && + while (Token::Match(type, "%name%|*|&|::|(") && !Token::Match(type, "typename|template") && type->varId() == 0 && !type->variable() && !type->function()) { if (type->str() == "(") { if (Token::Match(type->link(), ") const| {")) @@ -6058,7 +6058,11 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to const std::string& typestr(mSettings->library.returnValueType(tok->previous())); if (!typestr.empty()) { ValueType valuetype; - if (valuetype.fromLibraryType(typestr, mSettings)) { + TokenList tokenList(mSettings); + std::istringstream istr(typestr+";"); + tokenList.createTokens(istr); + if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings)) { + valuetype.originalTypeName = typestr; setValueType(tok, valuetype); } } @@ -6091,6 +6095,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to tokenList.simplifyPlatformTypes(); tokenList.simplifyStdType(); if (parsedecl(tokenList.front(), &vt, mDefaultSignedness, mSettings)) { + vt.originalTypeName = typestr; setValueType(tok, vt); } } @@ -6352,7 +6357,7 @@ std::string ValueType::dump() const ret << " valueType-typeScope=\"" << typeScope << '\"'; if (!originalTypeName.empty()) - ret << " valueType-originalTypeName=\"" << originalTypeName << '\"'; + ret << " valueType-originalTypeName=\"" << ErrorLogger::toxml(originalTypeName) << '\"'; return ret.str(); } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 01ec32d02..86cc5c01b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -3211,6 +3211,21 @@ static bool isNotEqual(std::pair x, std::pair x, const std::string& y) +{ + TokenList tokenList(nullptr); + std::istringstream istr(y); + tokenList.createTokens(istr); + return isNotEqual(x, std::make_pair(tokenList.front(), tokenList.back())); +} +static bool isNotEqual(std::pair x, const ValueType* y) +{ + if (y == nullptr) + return false; + if (y->originalTypeName.empty()) + return false; + return isNotEqual(x, y->originalTypeName); +} bool isLifetimeBorrowed(const Token *tok, const Settings *settings) { @@ -3240,6 +3255,10 @@ bool isLifetimeBorrowed(const Token *tok, const Settings *settings) std::pair parentdecl = Token::typeDecl(tok->astParent()); if (isNotEqual(decl, parentdecl)) return false; + if (isNotEqual(decl, tok->astParent()->valueType())) + return false; + if (isNotEqual(parentdecl, tok->valueType())) + return false; } } } else if (Token::Match(tok->astParent()->tokAt(-3), "%var% . push_back|push_front|insert|push (") && diff --git a/test/cfg/sqlite3.c b/test/cfg/sqlite3.c index 0437951dd..4a9a1856c 100644 --- a/test/cfg/sqlite3.c +++ b/test/cfg/sqlite3.c @@ -24,7 +24,6 @@ void validCode() { char * buf = sqlite3_malloc(10); - // cppcheck-suppress invalidPrintfArgType_uint printf("size: %ull\n", sqlite3_msize(buf)); sqlite3_free(buf); } diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index 8748b85e8..7d5320c88 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -975,7 +975,7 @@ private: "std::string &f() {\n" " return hello().substr(1);\n" "}"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.cpp:6]: (error) Reference to temporary returned.\n", errout.str()); check("class Foo;\n" "Foo hello() {\n" diff --git a/test/teststl.cpp b/test/teststl.cpp index 9ef75a799..4fc0226d1 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -4340,6 +4340,14 @@ private: "}\n",true); ASSERT_EQUALS("", errout.str()); + // #9783 + check("std::string GetTaskIDPerUUID(int);\n" + "void InitializeJumpList(CString s);\n" + "void foo() {\n" + " CString sAppID = GetTaskIDPerUUID(123).c_str();\n" + " InitializeJumpList(sAppID);\n" + "}\n",true); + ASSERT_EQUALS("", errout.str()); // #9796 check("struct A {};\n" "void f() {\n"