Avoid infinite recursion in getLifetimeVariable (#1634)
* Fix direct recursion * Limit depth of getLifetimeVariable
This commit is contained in:
parent
0b7414973d
commit
c176775afb
|
@ -2662,11 +2662,13 @@ std::string lifetimeType(const Token *tok, const ValueFlow::Value *val)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Variable *getLifetimeVariable(const Token *tok, ValueFlow::Value::ErrorPath &errorPath)
|
const Variable *getLifetimeVariable(const Token *tok, ValueFlow::Value::ErrorPath &errorPath, int depth)
|
||||||
{
|
{
|
||||||
if (!tok)
|
if (!tok)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
const Variable *var = tok->variable();
|
const Variable *var = tok->variable();
|
||||||
|
if (depth < 0)
|
||||||
|
return var;
|
||||||
if (var && var->declarationId() == tok->varId()) {
|
if (var && var->declarationId() == tok->varId()) {
|
||||||
if (var->isReference() || var->isRValueReference()) {
|
if (var->isReference() || var->isRValueReference()) {
|
||||||
if (!var->declEndToken())
|
if (!var->declEndToken())
|
||||||
|
@ -2680,7 +2682,7 @@ const Variable *getLifetimeVariable(const Token *tok, ValueFlow::Value::ErrorPat
|
||||||
if (vartok == tok)
|
if (vartok == tok)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (vartok)
|
if (vartok)
|
||||||
return getLifetimeVariable(vartok, errorPath);
|
return getLifetimeVariable(vartok, errorPath, depth-1);
|
||||||
} else {
|
} else {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2694,7 +2696,9 @@ const Variable *getLifetimeVariable(const Token *tok, ValueFlow::Value::ErrorPat
|
||||||
const Token *returnTok = findSimpleReturn(f);
|
const Token *returnTok = findSimpleReturn(f);
|
||||||
if (!returnTok)
|
if (!returnTok)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
const Variable *argvar = getLifetimeVariable(returnTok, errorPath);
|
if (returnTok == tok)
|
||||||
|
return var;
|
||||||
|
const Variable *argvar = getLifetimeVariable(returnTok, errorPath, depth-1);
|
||||||
if (!argvar)
|
if (!argvar)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) {
|
if (argvar->isArgument() && (argvar->isReference() || argvar->isRValueReference())) {
|
||||||
|
@ -2704,7 +2708,7 @@ const Variable *getLifetimeVariable(const Token *tok, ValueFlow::Value::ErrorPat
|
||||||
const Token *argTok = getArguments(tok->previous()).at(n);
|
const Token *argTok = getArguments(tok->previous()).at(n);
|
||||||
errorPath.emplace_back(returnTok, "Return reference.");
|
errorPath.emplace_back(returnTok, "Return reference.");
|
||||||
errorPath.emplace_back(tok->previous(), "Called function passing '" + argTok->str() + "'.");
|
errorPath.emplace_back(tok->previous(), "Called function passing '" + argTok->str() + "'.");
|
||||||
return getLifetimeVariable(argTok, errorPath);
|
return getLifetimeVariable(argTok, errorPath, depth-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return var;
|
return var;
|
||||||
|
|
|
@ -229,7 +229,7 @@ namespace ValueFlow {
|
||||||
std::string eitherTheConditionIsRedundant(const Token *condition);
|
std::string eitherTheConditionIsRedundant(const Token *condition);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Variable *getLifetimeVariable(const Token *tok, ValueFlow::Value::ErrorPath &errorPath);
|
const Variable *getLifetimeVariable(const Token *tok, ValueFlow::Value::ErrorPath &errorPath, int depth=20);
|
||||||
|
|
||||||
std::string lifetimeType(const Token *tok, const ValueFlow::Value *val);
|
std::string lifetimeType(const Token *tok, const ValueFlow::Value *val);
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ private:
|
||||||
TEST_CASE(returnReferenceCalculation);
|
TEST_CASE(returnReferenceCalculation);
|
||||||
TEST_CASE(returnReferenceLambda);
|
TEST_CASE(returnReferenceLambda);
|
||||||
TEST_CASE(returnReferenceInnerScope);
|
TEST_CASE(returnReferenceInnerScope);
|
||||||
|
TEST_CASE(returnReferenceRecursive);
|
||||||
|
|
||||||
TEST_CASE(danglingReference);
|
TEST_CASE(danglingReference);
|
||||||
|
|
||||||
|
@ -1246,6 +1247,15 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void returnReferenceRecursive() {
|
||||||
|
check("int& f() { return f(); }");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
check("int& g(int& i) { return i; }\n"
|
||||||
|
"int& f() { return g(f()); }\n");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
void danglingReference() {
|
void danglingReference() {
|
||||||
check("int f( int k )\n"
|
check("int f( int k )\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
|
Loading…
Reference in New Issue