Fix issue 10194: hang with followAllReferences() (#3189)
* Decrease depth faster when there is multiple returns
This commit is contained in:
parent
77716ee398
commit
9de976b243
|
@ -806,11 +806,11 @@ std::vector<ReferenceToken> followAllReferences(const Token* tok, bool inconclus
|
||||||
if (!Function::returnsReference(f))
|
if (!Function::returnsReference(f))
|
||||||
return {{tok, std::move(errors)}};
|
return {{tok, std::move(errors)}};
|
||||||
std::set<ReferenceToken, ReferenceTokenLess> result;
|
std::set<ReferenceToken, ReferenceTokenLess> result;
|
||||||
for (const Token* returnTok : Function::findReturns(f)) {
|
std::vector<const Token*> returns = Function::findReturns(f);
|
||||||
|
for (const Token* returnTok : returns) {
|
||||||
if (returnTok == tok)
|
if (returnTok == tok)
|
||||||
continue;
|
continue;
|
||||||
std::vector<ReferenceToken> argvarRt = followAllReferences(returnTok, inconclusive, errors, depth - 1);
|
for (const ReferenceToken& rt:followAllReferences(returnTok, inconclusive, errors, depth - returns.size())) {
|
||||||
for (const ReferenceToken& rt:followAllReferences(returnTok, inconclusive, errors, depth - 1)) {
|
|
||||||
const Variable* argvar = rt.token->variable();
|
const Variable* argvar = rt.token->variable();
|
||||||
if (!argvar)
|
if (!argvar)
|
||||||
return {{tok, std::move(errors)}};
|
return {{tok, std::move(errors)}};
|
||||||
|
@ -825,7 +825,7 @@ std::vector<ReferenceToken> followAllReferences(const Token* tok, bool inconclus
|
||||||
ErrorPath er = errors;
|
ErrorPath er = errors;
|
||||||
er.emplace_back(returnTok, "Return reference.");
|
er.emplace_back(returnTok, "Return reference.");
|
||||||
er.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
|
er.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
|
||||||
std::vector<ReferenceToken> refs = followAllReferences(argTok, inconclusive, std::move(er), depth - 1);
|
std::vector<ReferenceToken> refs = followAllReferences(argTok, inconclusive, std::move(er), depth - returns.size());
|
||||||
result.insert(refs.begin(), refs.end());
|
result.insert(refs.begin(), refs.end());
|
||||||
if (!inconclusive && result.size() > 1)
|
if (!inconclusive && result.size() > 1)
|
||||||
return {{tok, std::move(errors)}};
|
return {{tok, std::move(errors)}};
|
||||||
|
|
|
@ -2663,7 +2663,7 @@ std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, bool escape, Valu
|
||||||
for (const Token* returnTok : returns) {
|
for (const Token* returnTok : returns) {
|
||||||
if (returnTok == tok)
|
if (returnTok == tok)
|
||||||
continue;
|
continue;
|
||||||
for (LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, depth - 1)) {
|
for (LifetimeToken& lt : getLifetimeTokens(returnTok, escape, errorPath, depth - returns.size())) {
|
||||||
const Token* argvarTok = lt.token;
|
const Token* argvarTok = lt.token;
|
||||||
const Variable* argvar = argvarTok->variable();
|
const Variable* argvar = argvarTok->variable();
|
||||||
if (!argvar)
|
if (!argvar)
|
||||||
|
@ -2680,7 +2680,7 @@ std::vector<LifetimeToken> getLifetimeTokens(const Token* tok, bool escape, Valu
|
||||||
lt.errorPath.emplace_back(returnTok, "Return reference.");
|
lt.errorPath.emplace_back(returnTok, "Return reference.");
|
||||||
lt.errorPath.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
|
lt.errorPath.emplace_back(tok->previous(), "Called function passing '" + argTok->expressionString() + "'.");
|
||||||
std::vector<LifetimeToken> arglts = LifetimeToken::setInconclusive(
|
std::vector<LifetimeToken> arglts = LifetimeToken::setInconclusive(
|
||||||
getLifetimeTokens(argTok, escape, std::move(lt.errorPath), depth - 1), returns.size() > 1);
|
getLifetimeTokens(argTok, escape, std::move(lt.errorPath), depth - returns.size()), returns.size() > 1);
|
||||||
result.insert(result.end(), arglts.begin(), arglts.end());
|
result.insert(result.end(), arglts.begin(), arglts.end());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5447,6 +5447,47 @@ private:
|
||||||
" &b}}}};\n"
|
" &b}}}};\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
valueOfTok(code, "x");
|
valueOfTok(code, "x");
|
||||||
|
|
||||||
|
code = "int &a(int &);\n"
|
||||||
|
"int &b(int &);\n"
|
||||||
|
"int &c(int &);\n"
|
||||||
|
"int &d(int &e) {\n"
|
||||||
|
" if (!e)\n"
|
||||||
|
" return a(e);\n"
|
||||||
|
" if (e > 0)\n"
|
||||||
|
" return b(e);\n"
|
||||||
|
" if (e < 0)\n"
|
||||||
|
" return c(e);\n"
|
||||||
|
" return e;\n"
|
||||||
|
"}\n"
|
||||||
|
"int &a(int &e) { \n"
|
||||||
|
" if (!e)\n"
|
||||||
|
" return d(e); \n"
|
||||||
|
" if (e > 0)\n"
|
||||||
|
" return b(e);\n"
|
||||||
|
" if (e < 0)\n"
|
||||||
|
" return c(e);\n"
|
||||||
|
" return e;\n"
|
||||||
|
"}\n"
|
||||||
|
"int &b(int &e) { \n"
|
||||||
|
" if (!e)\n"
|
||||||
|
" return a(e); \n"
|
||||||
|
" if (e > 0)\n"
|
||||||
|
" return c(e);\n"
|
||||||
|
" if (e < 0)\n"
|
||||||
|
" return d(e);\n"
|
||||||
|
" return e;\n"
|
||||||
|
"}\n"
|
||||||
|
"int &c(int &e) { \n"
|
||||||
|
" if (!e)\n"
|
||||||
|
" return a(e); \n"
|
||||||
|
" if (e > 0)\n"
|
||||||
|
" return b(e);\n"
|
||||||
|
" if (e < 0)\n"
|
||||||
|
" return d(e);\n"
|
||||||
|
" return e;\n"
|
||||||
|
"}\n";
|
||||||
|
valueOfTok(code, "x");
|
||||||
}
|
}
|
||||||
|
|
||||||
void valueFlowCrashConstructorInitialization() { // #9577
|
void valueFlowCrashConstructorInitialization() { // #9577
|
||||||
|
|
Loading…
Reference in New Issue