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:
parent
bc39cd73f0
commit
0bb98aeef9
|
@ -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() ||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue