Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lib/tokenlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1765,9 +1765,16 @@ static Token * createAstAtToken(Token *tok)
if (Token::Match(tok, "%type% %name%|*|&|&&|::") && !Token::Match(tok, "return|new|delete")) {
int typecount = 0;
Token *typetok = tok;
while (Token::Match(typetok, "%type%|::|*|&|&&")) {
while (Token::Match(typetok, "%type%|::|*|&|&&|<")) {
if (typetok->isName() && !Token::simpleMatch(typetok->previous(), "::"))
typecount++;
if (typetok->str() == "<") {
if (Token* closing = typetok->findClosingBracket()) {
typetok = closing->next();
continue;
}
break;
}
typetok = typetok->next();
}
if (Token::Match(typetok, "%var% =") && typetok->varId())
Expand Down
5 changes: 4 additions & 1 deletion lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1948,7 +1948,10 @@ static bool isLifetimeBorrowed(const ValueType *vt, const ValueType *vtParent)
return true;
if (vtParent->pointer < vt->pointer && vtParent->isIntegral())
return true;
if (vtParent->str() == vt->str())
std::string vtParentStr = vtParent->str();
if (startsWith(vtParentStr, "const ")) // HACK: assignment to const
Comment thread
chrchr-github marked this conversation as resolved.
Outdated
vtParentStr.erase(0, 6);
if (vtParentStr == vt->str())
return true;
}

Expand Down
14 changes: 14 additions & 0 deletions test/testautovariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4122,6 +4122,20 @@ class TestAutoVariables : public TestFixture {
ASSERT_EQUALS("[test.cpp:9:63] -> [test.cpp:9:49] -> [test.cpp:10:11]: (error) Using iterator that is a temporary. [danglingTemporaryLifetime]\n",
errout_str());

check("struct A {\n" // #14054
" std::map<int, int> m_;\n"
"};\n"
"struct B {\n"
" A a_;\n"
"};\n"
"B func();\n"
"void f() {\n"
" const std::map<int, int>::iterator m = func().a_.m_.begin();\n"
" (void)m->first;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:9:62] -> [test.cpp:9:48] -> [test.cpp:10:11]: (error) Using iterator that is a temporary. [danglingTemporaryLifetime]\n",
errout_str());

check("void f(bool b) {\n"
" std::vector<int> ints = g();\n"
" auto *ptr = &ints;\n"
Expand Down
1 change: 1 addition & 0 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6788,6 +6788,7 @@ class TestTokenizer : public TestFixture {
ASSERT_EQUALS("unoRef:: var0(", testAst(code1));

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

ASSERT_EQUALS("", testAst("void *(*var)(int);"));
ASSERT_EQUALS("", testAst("void *(*var[2])(int);"));
Expand Down