From 12726ff7163abc8bc1bfe2a5e34c29cda75f390a Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:37:58 +0100 Subject: [PATCH 1/6] Update valueflow.cpp --- lib/valueflow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 8eb5735c986..b3bf773ecf3 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5861,6 +5861,12 @@ static void valueFlowSubFunction(const TokenList& tokenlist, continue; } + if (argvar->isReference() && isVariableChanged(argvar, settings)) { + argvalues.remove_if([](const ValueFlow::Value& v) { + return !v.isUninitValue(); + }); + } + if (argvalues.empty()) continue; From 2129a660ca6ec25772bfcab1eee4b4b1227c3ac8 Mon Sep 17 00:00:00 2001 From: chrchr-github <78114321+chrchr-github@users.noreply.github.com> Date: Fri, 5 Dec 2025 16:38:56 +0100 Subject: [PATCH 2/6] Update testnullpointer.cpp --- test/testnullpointer.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index ee971fd44a8..199bebac366 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -3020,6 +3020,21 @@ class TestNullPointer : public TestFixture { " f(nullptr, nullptr);\n" "}\n", dinit(CheckOptions, $.inconclusive = true)); ASSERT_EQUALS("", errout_str()); + + check("struct T {\n" // #14308 + " bool b{};\n" + " T* next{};\n" + "};\n" + "bool g(const T*& r) {\n" + " const T* t = r;\n" + " r = t->next;\n" + " return t->b;\n" + "}\n" + "void f(const T* tok) {\n" + " if (g(tok)) {}\n" + " if (tok) {}\n" + "}\n", dinit(CheckOptions, $.inconclusive = true)); + ASSERT_EQUALS("", errout_str()); } // Check if pointer is null and the dereference it From b2d34bf53151ee071252d43c453faad5cff6347d Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Thu, 11 Dec 2025 20:20:13 +0100 Subject: [PATCH 3/6] Set flow direction --- lib/valueflow.cpp | 4 ++-- lib/vf_analyzers.cpp | 1 + lib/vfvalue.cpp | 4 +++- lib/vfvalue.h | 14 ++++++++++++-- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b3bf773ecf3..1bf3058d7fa 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5861,9 +5861,9 @@ static void valueFlowSubFunction(const TokenList& tokenlist, continue; } - if (argvar->isReference() && isVariableChanged(argvar, settings)) { + if (argvar->isReference()) { argvalues.remove_if([](const ValueFlow::Value& v) { - return !v.isUninitValue(); + return v.isReverse(); }); } diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 104563b113b..cc15e6e4f61 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -1606,6 +1606,7 @@ ValuePtr makeAnalyzer(const Token* exprTok, ValueFlow::Value value, co ValuePtr makeReverseAnalyzer(const Token* exprTok, ValueFlow::Value value, const Settings& settings) { + value.setFlow(ValueFlow::Value::Flow::REVERSE); if (value.isContainerSizeValue()) return ContainerExpressionAnalyzer(exprTok, std::move(value), settings); return ExpressionAnalyzer(exprTok, std::move(value), settings); diff --git a/lib/vfvalue.cpp b/lib/vfvalue.cpp index cf1e07e65a3..3a8a427327d 100644 --- a/lib/vfvalue.cpp +++ b/lib/vfvalue.cpp @@ -27,7 +27,9 @@ namespace ValueFlow { Value::Value(const Token *c, MathLib::bigint val, Bound b) - : bound(b), + : valueType(ValueType::INT), + bound(b), + flow(Flow::UNKNOWN), safe(false), conditional(false), macro(false), diff --git a/lib/vfvalue.h b/lib/vfvalue.h index 8a473143b68..e18e051a5f2 100644 --- a/lib/vfvalue.h +++ b/lib/vfvalue.h @@ -45,7 +45,9 @@ namespace ValueFlow enum class Bound : std::uint8_t { Upper, Lower, Point }; explicit Value(MathLib::bigint val = 0, Bound b = Bound::Point) : + valueType(ValueType::INT), bound(b), + flow(Flow::UNKNOWN), safe(false), conditional(false), macro(false), @@ -212,7 +214,7 @@ namespace ValueFlow ITERATOR_START, ITERATOR_END, SYMBOLIC - } valueType = ValueType::INT; + } valueType : 4; bool isIntValue() const { return valueType == ValueType::INT; } @@ -267,7 +269,15 @@ namespace ValueFlow } /** The value bound */ - Bound bound = Bound::Point; + Bound bound : 2; + + enum class Flow : std::uint8_t { + UNKNOWN, + FORWARD, + REVERSE + } flow : 2; + bool isReverse() const { return flow == Flow::REVERSE; } + void setFlow(Flow f) { flow = f; } /** value relies on safe checking */ // cppcheck-suppress premium-misra-cpp-2023-12.2.1 From 32ee464e87ed9cc1c295455eca89513fc68e7fbf Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Thu, 11 Dec 2025 20:24:28 +0100 Subject: [PATCH 4/6] Format --- lib/vfvalue.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/vfvalue.h b/lib/vfvalue.h index e18e051a5f2..94764bae785 100644 --- a/lib/vfvalue.h +++ b/lib/vfvalue.h @@ -276,8 +276,12 @@ namespace ValueFlow FORWARD, REVERSE } flow : 2; - bool isReverse() const { return flow == Flow::REVERSE; } - void setFlow(Flow f) { flow = f; } + bool isReverse() const { + return flow == Flow::REVERSE; + } + void setFlow(Flow f) { + flow = f; + } /** value relies on safe checking */ // cppcheck-suppress premium-misra-cpp-2023-12.2.1 From 27282f278b15fdd04ecf9eb0256d292f472be44c Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Thu, 11 Dec 2025 20:44:35 +0100 Subject: [PATCH 5/6] Fix --- lib/vfvalue.cpp | 4 +--- lib/vfvalue.h | 32 +++++++++++++++----------------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/lib/vfvalue.cpp b/lib/vfvalue.cpp index 3a8a427327d..cf1e07e65a3 100644 --- a/lib/vfvalue.cpp +++ b/lib/vfvalue.cpp @@ -27,9 +27,7 @@ namespace ValueFlow { Value::Value(const Token *c, MathLib::bigint val, Bound b) - : valueType(ValueType::INT), - bound(b), - flow(Flow::UNKNOWN), + : bound(b), safe(false), conditional(false), macro(false), diff --git a/lib/vfvalue.h b/lib/vfvalue.h index 94764bae785..b6cdd13e60e 100644 --- a/lib/vfvalue.h +++ b/lib/vfvalue.h @@ -45,9 +45,7 @@ namespace ValueFlow enum class Bound : std::uint8_t { Upper, Lower, Point }; explicit Value(MathLib::bigint val = 0, Bound b = Bound::Point) : - valueType(ValueType::INT), bound(b), - flow(Flow::UNKNOWN), safe(false), conditional(false), macro(false), @@ -214,7 +212,7 @@ namespace ValueFlow ITERATOR_START, ITERATOR_END, SYMBOLIC - } valueType : 4; + } valueType = ValueType::INT; bool isIntValue() const { return valueType == ValueType::INT; } @@ -269,19 +267,7 @@ namespace ValueFlow } /** The value bound */ - Bound bound : 2; - - enum class Flow : std::uint8_t { - UNKNOWN, - FORWARD, - REVERSE - } flow : 2; - bool isReverse() const { - return flow == Flow::REVERSE; - } - void setFlow(Flow f) { - flow = f; - } + Bound bound = Bound::Point; /** value relies on safe checking */ // cppcheck-suppress premium-misra-cpp-2023-12.2.1 @@ -360,7 +346,19 @@ namespace ValueFlow }; UnknownFunctionReturn unknownFunctionReturn{UnknownFunctionReturn::no}; - long long : 24; // padding + enum class Flow : std::uint8_t { + UNKNOWN, + FORWARD, + REVERSE + } flow = Flow::UNKNOWN; + bool isReverse() const { + return flow == Flow::REVERSE; + } + void setFlow(Flow f) { + flow = f; + } + + long long : 16; // padding /** Path id */ MathLib::bigint path{}; From f57a6335f64ca99d8a4fbf89b5888d24bd2d8d1f Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sun, 14 Dec 2025 10:40:23 +0100 Subject: [PATCH 6/6] Reviewer comments --- lib/vf_analyzers.cpp | 2 +- lib/vfvalue.h | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index cc15e6e4f61..9af8b3b9b6e 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -1606,7 +1606,7 @@ ValuePtr makeAnalyzer(const Token* exprTok, ValueFlow::Value value, co ValuePtr makeReverseAnalyzer(const Token* exprTok, ValueFlow::Value value, const Settings& settings) { - value.setFlow(ValueFlow::Value::Flow::REVERSE); + value.setDirection(ValueFlow::Value::Direction::Reverse); if (value.isContainerSizeValue()) return ContainerExpressionAnalyzer(exprTok, std::move(value), settings); return ExpressionAnalyzer(exprTok, std::move(value), settings); diff --git a/lib/vfvalue.h b/lib/vfvalue.h index b6cdd13e60e..43c0c13c165 100644 --- a/lib/vfvalue.h +++ b/lib/vfvalue.h @@ -346,19 +346,19 @@ namespace ValueFlow }; UnknownFunctionReturn unknownFunctionReturn{UnknownFunctionReturn::no}; - enum class Flow : std::uint8_t { - UNKNOWN, - FORWARD, - REVERSE - } flow = Flow::UNKNOWN; + enum class Direction : std::uint8_t { + Unknown, + Forward, + Reverse + } direction = Direction::Unknown; bool isReverse() const { - return flow == Flow::REVERSE; + return direction == Direction::Reverse; } - void setFlow(Flow f) { - flow = f; + void setDirection(Direction d) { + direction = d; } - long long : 16; // padding + unsigned int : 16; // padding /** Path id */ MathLib::bigint path{};