Skip to content

Commit 23a698d

Browse files
Fix #14019 Bad AST for template reference type / #14054 FN danglingTemporaryLifetime with const iterator to subobject (#7722)
Co-authored-by: chrchr-github <noreply@github.com>
1 parent b46125e commit 23a698d

File tree

4 files changed

+29
-2
lines changed

4 files changed

+29
-2
lines changed

lib/tokenlist.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1765,9 +1765,16 @@ static Token * createAstAtToken(Token *tok)
17651765
if (Token::Match(tok, "%type% %name%|*|&|&&|::") && !Token::Match(tok, "return|new|delete")) {
17661766
int typecount = 0;
17671767
Token *typetok = tok;
1768-
while (Token::Match(typetok, "%type%|::|*|&|&&")) {
1768+
while (Token::Match(typetok, "%type%|::|*|&|&&|<")) {
17691769
if (typetok->isName() && !Token::simpleMatch(typetok->previous(), "::"))
17701770
typecount++;
1771+
if (typetok->str() == "<") {
1772+
if (Token* closing = typetok->findClosingBracket()) {
1773+
typetok = closing->next();
1774+
continue;
1775+
}
1776+
break;
1777+
}
17711778
typetok = typetok->next();
17721779
}
17731780
if (Token::Match(typetok, "%var% =") && typetok->varId())

lib/valueflow.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1949,7 +1949,12 @@ static bool isLifetimeBorrowed(const ValueType *vt, const ValueType *vtParent)
19491949
return true;
19501950
if (vtParent->pointer < vt->pointer && vtParent->isIntegral())
19511951
return true;
1952-
if (vtParent->str() == vt->str())
1952+
ValueType temp = *vtParent;
1953+
if ((temp.constness & 1) && !(vt->constness & 1)) // allow assignment to const/volatile
1954+
temp.constness &= ~1;
1955+
if ((temp.volatileness & 1) && !(vt->volatileness & 1))
1956+
temp.volatileness &= ~1;
1957+
if (temp.str() == vt->str())
19531958
return true;
19541959
}
19551960

test/testautovariables.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4122,6 +4122,20 @@ class TestAutoVariables : public TestFixture {
41224122
ASSERT_EQUALS("[test.cpp:9:63] -> [test.cpp:9:49] -> [test.cpp:10:11]: (error) Using iterator that is a temporary. [danglingTemporaryLifetime]\n",
41234123
errout_str());
41244124

4125+
check("struct A {\n" // #14054
4126+
" std::map<int, int> m_;\n"
4127+
"};\n"
4128+
"struct B {\n"
4129+
" A a_;\n"
4130+
"};\n"
4131+
"B func();\n"
4132+
"void f() {\n"
4133+
" const std::map<int, int>::iterator m = func().a_.m_.begin();\n"
4134+
" (void)m->first;\n"
4135+
"}\n");
4136+
ASSERT_EQUALS("[test.cpp:9:62] -> [test.cpp:9:48] -> [test.cpp:10:11]: (error) Using iterator that is a temporary. [danglingTemporaryLifetime]\n",
4137+
errout_str());
4138+
41254139
check("void f(bool b) {\n"
41264140
" std::vector<int> ints = g();\n"
41274141
" auto *ptr = &ints;\n"

test/testtokenize.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6788,6 +6788,7 @@ class TestTokenizer : public TestFixture {
67886788
ASSERT_EQUALS("unoRef:: var0(", testAst(code1));
67896789

67906790
ASSERT_EQUALS("vary=", testAst("std::string var = y;"));
6791+
ASSERT_EQUALS("vary=", testAst("std::unique_ptr<int> var = y;")); // #14019
67916792

67926793
ASSERT_EQUALS("", testAst("void *(*var)(int);"));
67936794
ASSERT_EQUALS("", testAst("void *(*var[2])(int);"));

0 commit comments

Comments
 (0)