Fix 9577 (endless recursion in Valueflow::bifurcate()) (#2492)

Ensure bifurcate() does not recurse endlessly where a variable is
initialized recursively, or a variable is initialized as x(0) or x{0}
followed by a recursive assignment (for example int x(0); x = x / 1;).

The first case is solved by bailing out if there initialization is done
using x(0) or x{0}, the second by adding a missing depth argument to a
recursive call.
This commit is contained in:
Rikard Falkeborn 2020-01-17 03:17:26 +01:00 committed by Daniel Marjamäki
parent bc39cd73f0
commit 0bb98aeef9
2 changed files with 31 additions and 1 deletions

View File

@ -2187,7 +2187,7 @@ static bool bifurcate(const Token* tok, const std::set<nonneg int>& varids, cons
if (tok->hasKnownIntValue())
return true;
if (Token::Match(tok, "%cop%"))
return bifurcate(tok->astOperand1(), varids, settings) && bifurcate(tok->astOperand2(), varids, settings, depth);
return bifurcate(tok->astOperand1(), varids, settings, depth) && bifurcate(tok->astOperand2(), varids, settings, depth);
if (Token::Match(tok, "%var%")) {
if (varids.count(tok->varId()) > 0)
return true;
@ -2197,6 +2197,8 @@ static bool bifurcate(const Token* tok, const std::set<nonneg int>& varids, cons
const Token* start = var->declEndToken();
if (!start)
return false;
if (start->strAt(-1) == ")" || start->strAt(-1) == "}")
return false;
if (Token::Match(start, "; %varid% =", var->declarationId()))
start = start->tokAt(2);
if (var->isConst() ||

View File

@ -132,6 +132,7 @@ private:
TEST_CASE(valueFlowCrashIncompleteCode);
TEST_CASE(valueFlowCrash);
TEST_CASE(valueFlowCrashConstructorInitialization);
}
static bool isNotTokValue(const ValueFlow::Value &val) {
@ -4398,6 +4399,33 @@ private:
"}\n";
valueOfTok(code, "0");
}
void valueFlowCrashConstructorInitialization() { // #9577
const char* code;
code = "void Error()\n"
"{\n"
" VfsPath path(\"\");\n"
" path = path / amtype;\n"
" size_t base = 0;\n"
" VfsPath standard(\"standard\");\n"
" if (path != standard)\n"
" {\n"
" }\n"
"}";
valueOfTok(code, "path");
code = "void Error()\n"
"{\n"
" VfsPath path;\n"
" path = path / amtype;\n"
" size_t base = 0;\n"
" VfsPath standard(\"standard\");\n"
" if (path != standard)\n"
" {\n"
" }\n"
"}";
valueOfTok(code, "path");
}
};
REGISTER_TEST(TestValueFlow)