diff --git a/lib/infer.cpp b/lib/infer.cpp index 8904def34..c06631cdd 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -148,7 +148,8 @@ struct Interval { result.setMinValue(minValue->intvalue + 1, minValue); if (minValue->isPossible() && minValue->bound == ValueFlow::Value::Bound::Lower) result.setMinValue(minValue->intvalue, minValue); - if (minValue->isKnown()) + if (!minValue->isImpossible() && minValue->bound == ValueFlow::Value::Bound::Point && + std::count_if(values.begin(), values.end(), predicate) == 1) return Interval::fromInt(minValue->intvalue, minValue); } const ValueFlow::Value* maxValue = getCompareValue(values, predicate, std::greater{}); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 9ffea1a16..7b294c5e6 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -6767,8 +6767,6 @@ static void valueFlowInferCondition(TokenList* tokenlist, if (result.size() != 1) continue; ValueFlow::Value value = result.front(); - value.intvalue = 1; - value.bound = ValueFlow::Value::Bound::Point; setTokenValue(tok, std::move(value), settings); } } diff --git a/test/testother.cpp b/test/testother.cpp index 43a398a0b..c5c6ad650 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -67,6 +67,7 @@ private: TEST_CASE(zeroDiv15); // #8319 TEST_CASE(zeroDiv16); // #11158 TEST_CASE(zeroDiv17); // #9931 + TEST_CASE(zeroDiv18); TEST_CASE(zeroDivCond); // division by zero / useless condition @@ -652,6 +653,17 @@ private: ASSERT_EQUALS("", errout.str()); } + void zeroDiv18() + { + check("int f(int x, int y) {\n" + " if (x == y) {}\n" + " return 1 / (x-y);\n" + "}\n"); + ASSERT_EQUALS( + "[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition 'x==y' is redundant or there is division by zero at line 3.\n", + errout.str()); + } + void zeroDivCond() { check("void f(unsigned int x) {\n" " int y = 17 / x;\n" diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 35b136e21..87c9cedea 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -5453,6 +5453,7 @@ private: void valueFlowConditionExpressions() { const char* code; + std::list values; // opposite condition code = "void f(int i, int j) {\n" @@ -5559,7 +5560,11 @@ private: " if (i != j) {}\n" " }\n" "}\n"; - ASSERT_EQUALS(true, removeImpossible(tokenValues(code, "!=")).empty()); + values = removeImpossible(tokenValues(code, "!=")); + ASSERT_EQUALS(1, values.size()); + ASSERT_EQUALS(0, values.front().intvalue); + ASSERT_EQUALS(true, values.front().isIntValue()); + ASSERT_EQUALS(true, values.front().isPossible()); code = "void f(bool b, int i, int j) {\n" " if (b || i == j) {} else {\n"