From bba6dfb8b2318329899dc0c4c6ed7f7d322d1100 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Thu, 3 Jan 2019 07:05:31 +0100 Subject: [PATCH] Fix issue 4744: ValueFlow: known integer result This fixes valueflow to have a value for `||` operator here: ```cpp bool f() { bool a = (4 == 3); // <-- 0 bool b = (3 == 3); // <-- 1 return a || b; // <-- 1 } ``` --- lib/valueflow.cpp | 6 +++++- test/testvalueflow.cpp | 13 +++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 940e8bb83..921f04846 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -283,13 +283,17 @@ static const Token * skipValueInConditionalExpression(const Token * const valuet if (prevIsLhs || !Token::Match(tok, "%oror%|&&|?|:")) continue; + if (tok->hasKnownIntValue()) + return tok; + // Is variable protected in LHS.. bool bailout = false; visitAstNodes(tok->astOperand1(), [&](const Token *tok2) { if (tok2->str() == ".") return ChildrenToVisit::none; // A variable is seen.. - if (tok2 != valuetok && tok2->variable() && (tok2->varId() == valuetok->varId() || !tok2->variable()->isArgument())) { + if (tok2 != valuetok && tok2->variable() && + (tok2->varId() == valuetok->varId() || (!tok2->variable()->isArgument() && !tok2->hasKnownIntValue()))) { // TODO: limit this bailout bailout = true; return ChildrenToVisit::done; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 856f0e930..81341c6e1 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -690,6 +690,19 @@ private: "}"; ASSERT_EQUALS(false, testValueOfX(code, 3U, 0)); + code = "bool f() {\n" + " bool a = (4 == 3);\n" + " bool b = (3 == 3);\n" + " return a || b;\n" + "}\n"; + values = tokenValues(code, "%oror%"); + ASSERT_EQUALS(1, values.size()); + if (!values.empty()) { + ASSERT_EQUALS(true, values.front().isIntValue()); + ASSERT_EQUALS(true, values.front().isKnown()); + ASSERT_EQUALS(1, values.front().intvalue); + } + // function call => calculation code = "void f(int x, int y) {\n" " a = x + y;\n"