From 5b7342fe5ffd4cdde9ed12e5c6837c63dd260ae3 Mon Sep 17 00:00:00 2001 From: Francois Berder Date: Mon, 20 May 2024 21:43:50 +0200 Subject: [PATCH] Fix 12681: FP: knownConditionTrueFalse While truncating integer values for upper/lower bounds, underflows/overflows must be handled correctly by inverting the bound. Signed-off-by: Francois Berder --- lib/valueflow.cpp | 20 ++++++++++++++++++-- test/testcondition.cpp | 9 +++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e9246920e4a..1eb7c620e48 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2833,8 +2833,24 @@ struct ValueFlowAnalyzer : Analyzer { const ValueType *dst = tok->valueType(); if (dst) { const size_t sz = ValueFlow::getSizeOf(*dst, settings); - if (sz > 0 && sz < 8) - value->intvalue = truncateIntValue(value->intvalue, sz, dst->sign); + if (sz > 0 && sz < 8) { + long long newvalue = truncateIntValue(value->intvalue, sz, dst->sign); + + /* Handle overflow/underflow for value bounds */ + if (value->bound != ValueFlow::Value::Bound::Point) { + if (newvalue > value->intvalue) { + if ((inc && value->bound == ValueFlow::Value::Bound::Lower) + || (!inc && value->bound == ValueFlow::Value::Bound::Upper)) + value->invertBound(); + } else if (newvalue < value->intvalue) { + if ((!inc && value->bound == ValueFlow::Value::Bound::Lower) + || (inc && value->bound == ValueFlow::Value::Bound::Upper)) + value->invertBound(); + } + } + + value->intvalue = newvalue; + } value->errorPath.emplace_back(tok, tok->str() + " is " + opName + "', new value is " + value->infoString()); } diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 8005c400e50..3a7d9ab41fa 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -4783,6 +4783,15 @@ class TestCondition : public TestFixture { " }\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + // #12681 + check("void f(unsigned u) {\n" + " if (u > 0) {\n" + " u--;\n" + " if (u == 0) {}\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void alwaysTrueInfer() {