Skip to content

Commit 32df807

Browse files
authored
Fix issue 9783: wrong lifetime analysis temporary assigned to object (#2711)
1 parent dea5a23 commit 32df807

7 files changed

Lines changed: 42 additions & 10 deletions

File tree

lib/astutils.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -169,17 +169,15 @@ std::string astCanonicalType(const Token *expr)
169169
{
170170
if (!expr)
171171
return "";
172-
if (expr->variable()) {
173-
const Variable *var = expr->variable();
172+
std::pair<const Token*, const Token*> decl = Token::typeDecl(expr);
173+
if (decl.first && decl.second) {
174174
std::string ret;
175-
for (const Token *type = var->typeStartToken(); Token::Match(type,"%name%|::") && type != var->nameToken(); type = type->next()) {
175+
for (const Token *type = decl.first; Token::Match(type,"%name%|::") && type != decl.second; type = type->next()) {
176176
if (!Token::Match(type, "const|static"))
177177
ret += type->str();
178178
}
179179
return ret;
180-
181180
}
182-
// TODO: handle expressions
183181
return "";
184182
}
185183

lib/errorlogger.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,9 @@ std::string ErrorLogger::toxml(const std::string &str)
682682
case '\"':
683683
xml << "&quot;";
684684
break;
685+
case '\'':
686+
xml << "&apos;";
687+
break;
685688
case '\0':
686689
xml << "\\0";
687690
break;

lib/symboldatabase.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5707,7 +5707,7 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V
57075707
} else
57085708
valuetype->type = ValueType::Type::RECORD;
57095709
bool par = false;
5710-
while (Token::Match(type, "%name%|*|&|::|(") && !Token::Match(type, "typename|template") &&
5710+
while (Token::Match(type, "%name%|*|&|::|(") && !Token::Match(type, "typename|template") && type->varId() == 0 &&
57115711
!type->variable() && !type->function()) {
57125712
if (type->str() == "(") {
57135713
if (Token::Match(type->link(), ") const| {"))
@@ -6058,7 +6058,11 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
60586058
const std::string& typestr(mSettings->library.returnValueType(tok->previous()));
60596059
if (!typestr.empty()) {
60606060
ValueType valuetype;
6061-
if (valuetype.fromLibraryType(typestr, mSettings)) {
6061+
TokenList tokenList(mSettings);
6062+
std::istringstream istr(typestr+";");
6063+
tokenList.createTokens(istr);
6064+
if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings)) {
6065+
valuetype.originalTypeName = typestr;
60626066
setValueType(tok, valuetype);
60636067
}
60646068
}
@@ -6091,6 +6095,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
60916095
tokenList.simplifyPlatformTypes();
60926096
tokenList.simplifyStdType();
60936097
if (parsedecl(tokenList.front(), &vt, mDefaultSignedness, mSettings)) {
6098+
vt.originalTypeName = typestr;
60946099
setValueType(tok, vt);
60956100
}
60966101
}
@@ -6352,7 +6357,7 @@ std::string ValueType::dump() const
63526357
ret << " valueType-typeScope=\"" << typeScope << '\"';
63536358

63546359
if (!originalTypeName.empty())
6355-
ret << " valueType-originalTypeName=\"" << originalTypeName << '\"';
6360+
ret << " valueType-originalTypeName=\"" << ErrorLogger::toxml(originalTypeName) << '\"';
63566361

63576362
return ret.str();
63586363
}

lib/valueflow.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3211,6 +3211,21 @@ static bool isNotEqual(std::pair<const Token*, const Token*> x, std::pair<const
32113211
start2 = skipCVRefs(start2, y.second);
32123212
return !(start1 == x.second && start2 == y.second);
32133213
}
3214+
static bool isNotEqual(std::pair<const Token*, const Token*> x, const std::string& y)
3215+
{
3216+
TokenList tokenList(nullptr);
3217+
std::istringstream istr(y);
3218+
tokenList.createTokens(istr);
3219+
return isNotEqual(x, std::make_pair(tokenList.front(), tokenList.back()));
3220+
}
3221+
static bool isNotEqual(std::pair<const Token*, const Token*> x, const ValueType* y)
3222+
{
3223+
if (y == nullptr)
3224+
return false;
3225+
if (y->originalTypeName.empty())
3226+
return false;
3227+
return isNotEqual(x, y->originalTypeName);
3228+
}
32143229

32153230
bool isLifetimeBorrowed(const Token *tok, const Settings *settings)
32163231
{
@@ -3240,6 +3255,10 @@ bool isLifetimeBorrowed(const Token *tok, const Settings *settings)
32403255
std::pair<const Token*, const Token*> parentdecl = Token::typeDecl(tok->astParent());
32413256
if (isNotEqual(decl, parentdecl))
32423257
return false;
3258+
if (isNotEqual(decl, tok->astParent()->valueType()))
3259+
return false;
3260+
if (isNotEqual(parentdecl, tok->valueType()))
3261+
return false;
32433262
}
32443263
}
32453264
} else if (Token::Match(tok->astParent()->tokAt(-3), "%var% . push_back|push_front|insert|push (") &&

test/cfg/sqlite3.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ void validCode()
2424

2525
{
2626
char * buf = sqlite3_malloc(10);
27-
// cppcheck-suppress invalidPrintfArgType_uint
2827
printf("size: %ull\n", sqlite3_msize(buf));
2928
sqlite3_free(buf);
3029
}

test/testautovariables.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -975,7 +975,7 @@ class TestAutoVariables : public TestFixture {
975975
"std::string &f() {\n"
976976
" return hello().substr(1);\n"
977977
"}");
978-
ASSERT_EQUALS("", errout.str());
978+
ASSERT_EQUALS("[test.cpp:6]: (error) Reference to temporary returned.\n", errout.str());
979979

980980
check("class Foo;\n"
981981
"Foo hello() {\n"

test/teststl.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4340,6 +4340,14 @@ class TestStl : public TestFixture {
43404340
"}\n",true);
43414341
ASSERT_EQUALS("", errout.str());
43424342

4343+
// #9783
4344+
check("std::string GetTaskIDPerUUID(int);\n"
4345+
"void InitializeJumpList(CString s);\n"
4346+
"void foo() {\n"
4347+
" CString sAppID = GetTaskIDPerUUID(123).c_str();\n"
4348+
" InitializeJumpList(sAppID);\n"
4349+
"}\n",true);
4350+
ASSERT_EQUALS("", errout.str());
43434351
// #9796
43444352
check("struct A {};\n"
43454353
"void f() {\n"

0 commit comments

Comments
 (0)