diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 8eb5735c986..1bf3058d7fa 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5861,6 +5861,12 @@ static void valueFlowSubFunction(const TokenList& tokenlist, continue; } + if (argvar->isReference()) { + argvalues.remove_if([](const ValueFlow::Value& v) { + return v.isReverse(); + }); + } + if (argvalues.empty()) continue; diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 104563b113b..9af8b3b9b6e 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.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 8a473143b68..43c0c13c165 100644 --- a/lib/vfvalue.h +++ b/lib/vfvalue.h @@ -346,7 +346,19 @@ namespace ValueFlow }; UnknownFunctionReturn unknownFunctionReturn{UnknownFunctionReturn::no}; - long long : 24; // padding + enum class Direction : std::uint8_t { + Unknown, + Forward, + Reverse + } direction = Direction::Unknown; + bool isReverse() const { + return direction == Direction::Reverse; + } + void setDirection(Direction d) { + direction = d; + } + + unsigned int : 16; // padding /** Path id */ MathLib::bigint path{}; 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