From 0bb98aeef91f7696fcc2f553fa5b889de1f69eee Mon Sep 17 00:00:00 2001 From: Rikard Falkeborn Date: Fri, 17 Jan 2020 03:17:26 +0100 Subject: [PATCH] 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. --- lib/valueflow.cpp | 4 +++- test/testvalueflow.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 24e825712..5f9722ed8 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2187,7 +2187,7 @@ static bool bifurcate(const Token* tok, const std::set& 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& 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() || diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 69b4949a2..7c43690bd 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -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)