Skip to content

Commit 9de976b

Browse files
authored
Fix issue 10194: hang with followAllReferences() (#3189)
* Decrease depth faster when there is multiple returns
1 parent 77716ee commit 9de976b

3 files changed

Lines changed: 47 additions & 6 deletions

File tree

lib/astutils.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -806,11 +806,11 @@ std::vector<ReferenceToken> followAllReferences(const Token* tok, bool inconclus
806806
if (!Function::returnsReference(f))
807807
return {{tok, std::move(errors)}};
808808
std::set<ReferenceToken, ReferenceTokenLess> result;
809-
for (const Token* returnTok : Function::findReturns(f)) {
809+
std::vector<const Token*> returns = Function::findReturns(f);
810+
for (const Token* returnTok : returns) {
810811
if (returnTok == tok)
811812
continue;
812-
std::vector<ReferenceToken> argvarRt = followAllReferences(returnTok, inconclusive, errors, depth - 1);
813-
for (const ReferenceToken& rt:followAllReferences(returnTok, inconclusive, errors, depth - 1)) {
813+
for (const ReferenceToken& rt:followAllReferences(returnTok, inconclusive, errors, depth - returns.size())) {
814814
const Variable* argvar = rt.token->variable();
815815
if (!argvar)
816816
return {{tok, std::move(errors)}};
@@ -825,7 +825,7 @@ std::vector<ReferenceToken> followAllReferences(const Token* tok, bool inconclus
825825
ErrorPath er = errors;
826826
er.emplace_back(returnTok, "Return reference.");
827827
er.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
828-
std::vector<ReferenceToken> refs = followAllReferences(argTok, inconclusive, std::move(er), depth - 1);
828+
std::vector<ReferenceToken> refs = followAllReferences(argTok, inconclusive, std::move(er), depth - returns.size());
829829
result.insert(refs.begin(), refs.end());
830830
if (!inconclusive && result.size() > 1)
831831
return {{tok, std::move(errors)}};

lib/valueflow.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,7 +2663,7 @@ std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, bool escape, Valu
26632663
for (const Token* returnTok : returns) {
26642664
if (returnTok == tok)
26652665
continue;
2666-
for (LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, depth - 1)) {
2666+
for (LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, depth - returns.size())) {
26672667
const Token* argvarTok = lt.token;
26682668
const Variable* argvar = argvarTok->variable();
26692669
if (!argvar)
@@ -2680,7 +2680,7 @@ std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, bool escape, Valu
26802680
lt.errorPath.emplace_back(returnTok, "Return reference.");
26812681
lt.errorPath.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
26822682
std::vector<LifetimeToken> arglts = LifetimeToken::setInconclusive(
2683-
getLifetimeTokens(argTok, escape, std::move(lt.errorPath), depth - 1), returns.size() > 1);
2683+
getLifetimeTokens(argTok, escape, std::move(lt.errorPath), depth - returns.size()), returns.size() > 1);
26842684
result.insert(result.end(), arglts.begin(), arglts.end());
26852685
}
26862686
}

test/testvalueflow.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5447,6 +5447,47 @@ class TestValueFlow : public TestFixture {
54475447
" &b}}}};\n"
54485448
"}\n";
54495449
valueOfTok(code, "x");
5450+
5451+
code = "int &a(int &);\n"
5452+
"int &b(int &);\n"
5453+
"int &c(int &);\n"
5454+
"int &d(int &e) {\n"
5455+
" if (!e)\n"
5456+
" return a(e);\n"
5457+
" if (e > 0)\n"
5458+
" return b(e);\n"
5459+
" if (e < 0)\n"
5460+
" return c(e);\n"
5461+
" return e;\n"
5462+
"}\n"
5463+
"int &a(int &e) { \n"
5464+
" if (!e)\n"
5465+
" return d(e); \n"
5466+
" if (e > 0)\n"
5467+
" return b(e);\n"
5468+
" if (e < 0)\n"
5469+
" return c(e);\n"
5470+
" return e;\n"
5471+
"}\n"
5472+
"int &b(int &e) { \n"
5473+
" if (!e)\n"
5474+
" return a(e); \n"
5475+
" if (e > 0)\n"
5476+
" return c(e);\n"
5477+
" if (e < 0)\n"
5478+
" return d(e);\n"
5479+
" return e;\n"
5480+
"}\n"
5481+
"int &c(int &e) { \n"
5482+
" if (!e)\n"
5483+
" return a(e); \n"
5484+
" if (e > 0)\n"
5485+
" return b(e);\n"
5486+
" if (e < 0)\n"
5487+
" return d(e);\n"
5488+
" return e;\n"
5489+
"}\n";
5490+
valueOfTok(code, "x");
54505491
}
54515492

54525493
void valueFlowCrashConstructorInitialization() { // #9577

0 commit comments

Comments
 (0)