Fix issue 9783: wrong lifetime analysis temporary assigned to object (#2711)
This commit is contained in:
parent
dea5a23c34
commit
32df807b22
|
@ -169,17 +169,15 @@ std::string astCanonicalType(const Token *expr)
|
|||
{
|
||||
if (!expr)
|
||||
return "";
|
||||
if (expr->variable()) {
|
||||
const Variable *var = expr->variable();
|
||||
std::pair<const Token*, const Token*> 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 "";
|
||||
}
|
||||
|
||||
|
|
|
@ -682,6 +682,9 @@ std::string ErrorLogger::toxml(const std::string &str)
|
|||
case '\"':
|
||||
xml << """;
|
||||
break;
|
||||
case '\'':
|
||||
xml << "'";
|
||||
break;
|
||||
case '\0':
|
||||
xml << "\\0";
|
||||
break;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -3211,6 +3211,21 @@ static bool isNotEqual(std::pair<const Token*, const Token*> x, std::pair<const
|
|||
start2 = skipCVRefs(start2, y.second);
|
||||
return !(start1 == x.second && start2 == y.second);
|
||||
}
|
||||
static bool isNotEqual(std::pair<const Token*, const Token*> 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<const Token*, const Token*> 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<const Token*, const Token*> 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 (") &&
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue