From 607b455e48e6752cde6dc1d00f01d1834658cbe6 Mon Sep 17 00:00:00 2001 From: firewave Date: Fri, 8 Aug 2025 15:39:43 +0200 Subject: [PATCH] got rid of unnecessary `ExprIdToken` constructors --- lib/programmemory.cpp | 38 ++++++++++++++++++++++++++++++++------ lib/programmemory.h | 9 +++------ test/testprogrammemory.cpp | 19 +++++++++++++++++++ 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 9882cba2a3c..573a4dfe96d 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -75,9 +75,10 @@ void ProgramMemory::setValue(const Token* expr, const ValueFlow::Value& value) { if (subexpr) (*mValues)[subexpr] = std::move(subvalue); } + const ValueFlow::Value* ProgramMemory::getValue(nonneg int exprid, bool impossible) const { - const auto it = utils::as_const(*mValues).find(exprid); + const auto it = find(exprid); const bool found = it != mValues->cend() && (impossible || !it->second.isImpossible()); if (found) return &it->second; @@ -154,18 +155,28 @@ void ProgramMemory::setUnknown(const Token* expr) { (*mValues)[expr].valueType = ValueFlow::Value::ValueType::UNINIT; } -bool ProgramMemory::hasValue(nonneg int exprid) +bool ProgramMemory::hasValue(nonneg int exprid) const { - return mValues->find(exprid) != mValues->end(); + const auto it = find(exprid); + return it != mValues->cend(); } const ValueFlow::Value& ProgramMemory::at(nonneg int exprid) const { - return mValues->at(exprid); + const auto it = find(exprid); + if (it == mValues->cend()) { + throw std::out_of_range("ProgramMemory::at"); + } + return it->second; } + ValueFlow::Value& ProgramMemory::at(nonneg int exprid) { copyOnWrite(); - return mValues->at(exprid); + const auto it = find(exprid); + if (it == mValues->end()) { + throw std::out_of_range("ProgramMemory::at"); + } + return it->second; } void ProgramMemory::erase_if(const std::function& pred) @@ -225,6 +236,21 @@ void ProgramMemory::copyOnWrite() mValues = std::make_shared(*mValues); } +ProgramMemory::Map::const_iterator ProgramMemory::find(nonneg int exprid) const +{ + const auto& cvalues = utils::as_const(*mValues); + return std::find_if(cvalues.cbegin(), cvalues.cend(), [&exprid](const Map::value_type& entry) { + return entry.first.getExpressionId() == exprid; + }); +} + +ProgramMemory::Map::iterator ProgramMemory::find(nonneg int exprid) +{ + return std::find_if(mValues->begin(), mValues->end(), [&exprid](const Map::value_type& entry) { + return entry.first.getExpressionId() == exprid; + }); +} + static ValueFlow::Value execute(const Token* expr, ProgramMemory& pm, const Settings& settings); static bool evaluateCondition(MathLib::bigint r, const Token* condition, ProgramMemory& pm, const Settings& settings) @@ -395,7 +421,7 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok bool setvar = false; const Token* vartok = tok2->astOperand1(); for (const auto& p:vars) { - if (p.first != vartok->exprId()) + if (p.first.getExpressionId() != vartok->exprId()) continue; if (vartok == tok) continue; diff --git a/lib/programmemory.h b/lib/programmemory.h index 36b453b71de..1bd7ca78a4b 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -41,14 +41,9 @@ struct ExprIdToken { const Token* tok = nullptr; nonneg int exprid = 0; - ExprIdToken() = default; // cppcheck-suppress noExplicitConstructor // NOLINTNEXTLINE(google-explicit-constructor) ExprIdToken(const Token* tok); - // TODO: Make this constructor only available from ProgramMemory - // cppcheck-suppress noExplicitConstructor - // NOLINTNEXTLINE(google-explicit-constructor) - ExprIdToken(nonneg int exprid) : exprid(exprid) {} nonneg int getExpressionId() const; @@ -117,7 +112,7 @@ struct CPPCHECKLIB ProgramMemory { void setUnknown(const Token* expr); bool getTokValue(nonneg int exprid, const Token*& result) const; - bool hasValue(nonneg int exprid); + bool hasValue(nonneg int exprid) const; const ValueFlow::Value& at(nonneg int exprid) const; ValueFlow::Value& at(nonneg int exprid); @@ -150,6 +145,8 @@ struct CPPCHECKLIB ProgramMemory { private: void copyOnWrite(); + Map::const_iterator find(nonneg int exprid) const; + Map::iterator find(nonneg int exprid); std::shared_ptr mValues; }; diff --git a/test/testprogrammemory.cpp b/test/testprogrammemory.cpp index 63682e0f10a..13a5f8e639a 100644 --- a/test/testprogrammemory.cpp +++ b/test/testprogrammemory.cpp @@ -30,6 +30,9 @@ class TestProgramMemory : public TestFixture { private: void run() override { TEST_CASE(copyOnWrite); + TEST_CASE(hasValue); + TEST_CASE(getValue); + TEST_CASE(at); } void copyOnWrite() const { @@ -79,6 +82,22 @@ class TestProgramMemory : public TestFixture { ASSERT(v); ASSERT_EQUALS(41, v->intvalue); } + + void hasValue() const { + ProgramMemory pm; + ASSERT(!pm.hasValue(123)); + } + + void getValue() const { + ProgramMemory pm; + ASSERT(!pm.getValue(123)); + } + + void at() const { + ProgramMemory pm; + ASSERT_THROW_EQUALS_2(pm.at(123), std::out_of_range, "ProgramMemory::at"); + ASSERT_THROW_EQUALS_2(utils::as_const(pm).at(123), std::out_of_range, "ProgramMemory::at"); + } }; REGISTER_TEST(TestProgramMemory)