Skip to content

Commit cefc105

Browse files
authored
Fix 11468: false positive danglingTempReference warning (#4679)
1 parent aab3d30 commit cefc105

File tree

2 files changed

+35
-9
lines changed

2 files changed

+35
-9
lines changed

lib/valueflow.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4079,19 +4079,20 @@ struct LifetimeStore {
40794079
}
40804080

40814081
template<class Predicate>
4082-
void byDerefCopy(Token* tok,
4082+
bool byDerefCopy(Token* tok,
40834083
TokenList* tokenlist,
40844084
ErrorLogger* errorLogger,
40854085
const Settings* settings,
40864086
Predicate pred,
40874087
SourceLocation loc = SourceLocation::current()) const
40884088
{
4089+
bool update = false;
40894090
if (!settings->certainty.isEnabled(Certainty::inconclusive) && inconclusive)
4090-
return;
4091+
return update;
40914092
if (!argtok)
4092-
return;
4093+
return update;
40934094
if (!tok)
4094-
return;
4095+
return update;
40954096
for (const ValueFlow::Value &v : argtok->values()) {
40964097
if (!v.isLifetimeValue())
40974098
continue;
@@ -4105,20 +4106,22 @@ struct LifetimeStore {
41054106
const Token * const varDeclEndToken = var->declEndToken();
41064107
for (const Token *tok3 = tok; tok3 && tok3 != varDeclEndToken; tok3 = tok3->previous()) {
41074108
if (tok3->varId() == var->declarationId()) {
4108-
LifetimeStore{tok3, message, type, inconclusive}.byVal(tok, tokenlist, errorLogger, settings, pred, loc);
4109+
update |= LifetimeStore{tok3, message, type, inconclusive}
4110+
.byVal(tok, tokenlist, errorLogger, settings, pred, loc);
41094111
break;
41104112
}
41114113
}
41124114
}
4115+
return update;
41134116
}
41144117

4115-
void byDerefCopy(Token* tok,
4118+
bool byDerefCopy(Token* tok,
41164119
TokenList* tokenlist,
41174120
ErrorLogger* errorLogger,
41184121
const Settings* settings,
41194122
SourceLocation loc = SourceLocation::current()) const
41204123
{
4121-
byDerefCopy(
4124+
return byDerefCopy(
41224125
tok,
41234126
tokenlist,
41244127
errorLogger,
@@ -4348,9 +4351,14 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog
43484351
ls.forward = false;
43494352
ls.errorPath = v.errorPath;
43504353
ls.errorPath.emplace_front(returnTok, "Return " + lifetimeType(returnTok, &v) + ".");
4351-
if (v.lifetimeScope == ValueFlow::Value::LifetimeScope::ThisValue)
4354+
int thisIndirect = v.lifetimeScope == ValueFlow::Value::LifetimeScope::ThisValue ? 0 : 1;
4355+
if (derefShared(memtok->astParent()))
4356+
thisIndirect--;
4357+
if (thisIndirect == -1)
4358+
update |= ls.byDerefCopy(tok->next(), tokenlist, errorLogger, settings);
4359+
else if (thisIndirect == 0)
43524360
update |= ls.byVal(tok->next(), tokenlist, errorLogger, settings);
4353-
else
4361+
else if (thisIndirect == 1)
43544362
update |= ls.byRef(tok->next(), tokenlist, errorLogger, settings);
43554363
continue;
43564364
}

test/testautovariables.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,6 +2004,24 @@ class TestAutoVariables : public TestFixture {
20042004
ASSERT_EQUALS(
20052005
"[test.cpp:11] -> [test.cpp:2] -> [test.cpp:11] -> [test.cpp:12]: (error) Using reference to dangling temporary.\n",
20062006
errout.str());
2007+
2008+
check("struct C {\n"
2009+
" std::vector<std::vector<int>> v;\n"
2010+
"};\n"
2011+
"struct P {\n"
2012+
" std::vector<C*>::const_iterator find() const { return pv.begin(); }\n"
2013+
" std::vector<C*> pv;\n"
2014+
"};\n"
2015+
"struct M {\n"
2016+
" const P* get() const { return p; }\n"
2017+
" P* p;\n"
2018+
"};\n"
2019+
"void f(const M* m) {\n"
2020+
" auto it = m->get()->find();\n"
2021+
" auto e = (*it)->v.begin();\n"
2022+
" const int& x = (*e)[1];\n"
2023+
"}\n");
2024+
ASSERT_EQUALS("", errout.str());
20072025
}
20082026

20092027
void testglobalnamespace() {

0 commit comments

Comments
 (0)