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())
|
if (tok->hasKnownIntValue())
|
||||||
return true;
|
return true;
|
||||||
if (Token::Match(tok, "%cop%"))
|
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 (Token::Match(tok, "%var%")) {
|
||||||
if (varids.count(tok->varId()) > 0)
|
if (varids.count(tok->varId()) > 0)
|
||||||
return true;
|
return true;
|
||||||
|
@ -2197,6 +2197,8 @@ static bool bifurcate(const Token* tok, const std::set<nonneg int>& varids, cons
|
||||||
const Token* start = var->declEndToken();
|
const Token* start = var->declEndToken();
|
||||||
if (!start)
|
if (!start)
|
||||||
return false;
|
return false;
|
||||||
|
if (start->strAt(-1) == ")" || start->strAt(-1) == "}")
|
||||||
|
return false;
|
||||||
if (Token::Match(start, "; %varid% =", var->declarationId()))
|
if (Token::Match(start, "; %varid% =", var->declarationId()))
|
||||||
start = start->tokAt(2);
|
start = start->tokAt(2);
|
||||||
if (var->isConst() ||
|
if (var->isConst() ||
|
||||||
|
|
|
@ -132,6 +132,7 @@ private:
|
||||||
TEST_CASE(valueFlowCrashIncompleteCode);
|
TEST_CASE(valueFlowCrashIncompleteCode);
|
||||||
|
|
||||||
TEST_CASE(valueFlowCrash);
|
TEST_CASE(valueFlowCrash);
|
||||||
|
TEST_CASE(valueFlowCrashConstructorInitialization);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isNotTokValue(const ValueFlow::Value &val) {
|
static bool isNotTokValue(const ValueFlow::Value &val) {
|
||||||
|
@ -4398,6 +4399,33 @@ private:
|
||||||
"}\n";
|
"}\n";
|
||||||
valueOfTok(code, "0");
|
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)
|
REGISTER_TEST(TestValueFlow)
|
||||||
|
|
Loading…
Reference in New Issue