From ea3b82ede50c48d77095d336af3a9a46a7433a81 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 8 Jul 2025 09:11:00 -0500 Subject: [PATCH 1/9] Use new pm --- lib/programmemory.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 9882cba2a3c..e1c535f89d5 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -489,13 +489,14 @@ static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars) void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars) { - ProgramMemory pm = state; - addVars(pm, vars); - fillProgramMemoryFromConditions(pm, tok, settings); - ProgramMemory local = pm; + ProgramMemory local = state; + addVars(local, vars); + fillProgramMemoryFromConditions(local, tok, settings); + ProgramMemory pm; fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); - addVars(pm, vars); - replace(std::move(pm), tok); + local.replace(std::move(pm)); + addVars(local, vars); + replace(std::move(local), tok); } void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty) From 2d61478c85d2e16392b3b9c43b693234e56ebe23 Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 8 Aug 2025 17:39:14 -0500 Subject: [PATCH 2/9] Add ifdef --- lib/programmemory.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index e1c535f89d5..744bfe7e274 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -489,6 +489,7 @@ static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars) void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars) { +#if 0 ProgramMemory local = state; addVars(local, vars); fillProgramMemoryFromConditions(local, tok, settings); @@ -497,6 +498,15 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va local.replace(std::move(pm)); addVars(local, vars); replace(std::move(local), tok); +#else + ProgramMemory pm = state; + addVars(pm, vars); + fillProgramMemoryFromConditions(pm, tok, settings); + ProgramMemory local = pm; + fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); + addVars(pm, vars); + replace(std::move(pm), tok); +#endif } void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty) From 417e0a7619c352f68c0e4e2ed08e70d0c5d143b4 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 18 Aug 2025 08:07:44 -0500 Subject: [PATCH 3/9] Add ifdef and prints --- lib/programmemory.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 744bfe7e274..a0a12787e5a 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -45,6 +45,8 @@ #include #include +#include + ExprIdToken::ExprIdToken(const Token* tok) : tok(tok), exprid(tok ? tok->exprId() : 0) {} nonneg int ExprIdToken::getExpressionId() const { @@ -487,9 +489,20 @@ static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars) } } +static void debugPrint(const ProgramMemory& pm) +{ + for(auto&& p:pm) { + std::cout << p.first->expressionString() << " => " << p.second.toString() << std::endl; + } +} + void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars) { -#if 0 + std::cout << "**************************************************************\n"; + std::cout << "addState: " << tok->expressionString() << std::endl; + std::cout << "Before:\n"; + debugPrint(state); +#if 1 ProgramMemory local = state; addVars(local, vars); fillProgramMemoryFromConditions(local, tok, settings); @@ -507,6 +520,8 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va addVars(pm, vars); replace(std::move(pm), tok); #endif + std::cout << "After:\n"; + debugPrint(state); } void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty) From d7ddf777b7e53a73b9bed1eef96650fc5f6bbd62 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 15 Sep 2025 17:53:56 -0500 Subject: [PATCH 4/9] Fix unit tests --- lib/programmemory.cpp | 50 ++++++++++++++++++++++++++++++++++--------- lib/programmemory.h | 2 +- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index a0a12787e5a..3faec3d32d4 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -207,7 +207,7 @@ bool ProgramMemory::empty() const } // NOLINTNEXTLINE(performance-unnecessary-value-param) - technically correct but we are moving the given values -void ProgramMemory::replace(ProgramMemory pm) +void ProgramMemory::replace(ProgramMemory pm, bool skipUnknown) { if (pm.empty()) return; @@ -215,6 +215,11 @@ void ProgramMemory::replace(ProgramMemory pm) copyOnWrite(); for (auto&& p : (*pm.mValues)) { + if(skipUnknown) { + auto it = mValues->find(p.first); + if(it != mValues->end() && it->second.isUninitValue()) + continue; + } (*mValues)[p.first] = std::move(p.second); } } @@ -407,7 +412,8 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok if (!setvar) { if (!pm.hasValue(vartok->exprId())) { const Token* valuetok = tok2->astOperand2(); - pm.setValue(vartok, execute(valuetok, pm, settings)); + ProgramMemory local = state; + pm.setValue(vartok, execute(valuetok, local, settings)); } } } else if (tok2->exprId() > 0 && Token::Match(tok2, ".|(|[|*|%var%") && !pm.hasValue(tok2->exprId()) && @@ -478,7 +484,7 @@ void ProgramMemoryState::replace(ProgramMemory pm, const Token* origin) if (origin) for (const auto& p : pm) origins[p.first.getExpressionId()] = origin; - state.replace(std::move(pm)); + state.replace(std::move(pm), true); } static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars) @@ -492,26 +498,50 @@ static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars) static void debugPrint(const ProgramMemory& pm) { for(auto&& p:pm) { - std::cout << p.first->expressionString() << " => " << p.second.toString() << std::endl; + if(p.first.tok) + std::cout << p.first->expressionString(); + else + std::cout << p.first.exprid; + std::cout << " => " << p.second.toString() << std::endl; } } void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars) { - std::cout << "**************************************************************\n"; - std::cout << "addState: " << tok->expressionString() << std::endl; - std::cout << "Before:\n"; - debugPrint(state); + // std::cout << "**************************************************************\n"; + // std::cout << "addState: " << tok->expressionString() << std::endl; + // std::cout << "Before:\n"; + // debugPrint(state); #if 1 + // ProgramMemory local = state; + // addVars(local, vars); + // fillProgramMemoryFromConditions(local, tok, settings); + // ProgramMemory pm; + // fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); + // local.replace(std::move(pm)); + // addVars(local, vars); + // replace(std::move(local), tok); + ProgramMemory local = state; addVars(local, vars); fillProgramMemoryFromConditions(local, tok, settings); ProgramMemory pm; fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); local.replace(std::move(pm)); + // ProgramMemory local2 = local; + // fillProgramMemoryFromAssignments(local, tok, settings, local2, vars); addVars(local, vars); replace(std::move(local), tok); #else + // ProgramMemory pm = state; + // addVars(pm, vars); + // for(int i =0;i<4;i++) { + // fillProgramMemoryFromConditions(pm, tok, settings); + // ProgramMemory local = pm; + // fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); + // } + // replace(std::move(pm), tok); + ProgramMemory pm = state; addVars(pm, vars); fillProgramMemoryFromConditions(pm, tok, settings); @@ -520,8 +550,8 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va addVars(pm, vars); replace(std::move(pm), tok); #endif - std::cout << "After:\n"; - debugPrint(state); + // std::cout << "After:\n"; + // debugPrint(state); } void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty) diff --git a/lib/programmemory.h b/lib/programmemory.h index 36b453b71de..b2281669c0b 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -130,7 +130,7 @@ struct CPPCHECKLIB ProgramMemory { bool empty() const; - void replace(ProgramMemory pm); + void replace(ProgramMemory pm, bool skipUnknown = false); Map::const_iterator begin() const { return mValues->cbegin(); From 19de4810da0d0e5e9f9b210b06a7acee3d7eb963 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 15 Sep 2025 17:54:06 -0500 Subject: [PATCH 5/9] Format --- lib/programmemory.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 3faec3d32d4..eb0415a0aec 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -215,9 +215,9 @@ void ProgramMemory::replace(ProgramMemory pm, bool skipUnknown) copyOnWrite(); for (auto&& p : (*pm.mValues)) { - if(skipUnknown) { + if (skipUnknown) { auto it = mValues->find(p.first); - if(it != mValues->end() && it->second.isUninitValue()) + if (it != mValues->end() && it->second.isUninitValue()) continue; } (*mValues)[p.first] = std::move(p.second); @@ -497,8 +497,8 @@ static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars) static void debugPrint(const ProgramMemory& pm) { - for(auto&& p:pm) { - if(p.first.tok) + for (auto&& p : pm) { + if (p.first.tok) std::cout << p.first->expressionString(); else std::cout << p.first.exprid; From a107e8515820e4a476faf8dbff1067c8e56cc5b2 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 16 Sep 2025 09:03:00 -0500 Subject: [PATCH 6/9] Add test --- test/testuninitvar.cpp | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index dfdc048b4f9..dfd1eeb9529 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -6588,6 +6588,23 @@ class TestUninitVar : public TestFixture { " return c.front();\n" "}\n"); ASSERT_EQUALS("[test.cpp:8:12]: (error) Uninitialized variable: c [uninitvar]\n", errout_str()); + + // #13930 + valueFlowUninit("extern int32_t g_items[10U];\n" + "uint16_t write_item(uint8_t n);\n" + "uint16_t write_item(uint8_t n) {\n" + " int32_t *p_item = NULL;\n" + " uint16_t ret;\n" + " ret = 0U;\n" + " if (n < 10U)\n" + " p_item = &g_items[n];\n" + " else\n" + " ret = 1U;\n" + " if (ret == 0U) \n" + " *p_item = 5;\n" + " return ret;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value From feb4cf498c507cd61e0e2b96f2f90b5d1b61f243 Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 16 Sep 2025 09:06:19 -0500 Subject: [PATCH 7/9] Remove comments --- lib/programmemory.cpp | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index eb0415a0aec..ffa1313e69e 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -508,50 +508,14 @@ static void debugPrint(const ProgramMemory& pm) void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars) { - // std::cout << "**************************************************************\n"; - // std::cout << "addState: " << tok->expressionString() << std::endl; - // std::cout << "Before:\n"; - // debugPrint(state); -#if 1 - // ProgramMemory local = state; - // addVars(local, vars); - // fillProgramMemoryFromConditions(local, tok, settings); - // ProgramMemory pm; - // fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); - // local.replace(std::move(pm)); - // addVars(local, vars); - // replace(std::move(local), tok); - ProgramMemory local = state; addVars(local, vars); fillProgramMemoryFromConditions(local, tok, settings); ProgramMemory pm; fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); local.replace(std::move(pm)); - // ProgramMemory local2 = local; - // fillProgramMemoryFromAssignments(local, tok, settings, local2, vars); addVars(local, vars); replace(std::move(local), tok); -#else - // ProgramMemory pm = state; - // addVars(pm, vars); - // for(int i =0;i<4;i++) { - // fillProgramMemoryFromConditions(pm, tok, settings); - // ProgramMemory local = pm; - // fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); - // } - // replace(std::move(pm), tok); - - ProgramMemory pm = state; - addVars(pm, vars); - fillProgramMemoryFromConditions(pm, tok, settings); - ProgramMemory local = pm; - fillProgramMemoryFromAssignments(pm, tok, settings, local, vars); - addVars(pm, vars); - replace(std::move(pm), tok); -#endif - // std::cout << "After:\n"; - // debugPrint(state); } void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty) From 7b55579b95d0ce0a86de304b31c6cc9da3cf2d7d Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 16 Sep 2025 09:36:35 -0500 Subject: [PATCH 8/9] Remove debug print --- lib/programmemory.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index ffa1313e69e..902992aff40 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -45,8 +45,6 @@ #include #include -#include - ExprIdToken::ExprIdToken(const Token* tok) : tok(tok), exprid(tok ? tok->exprId() : 0) {} nonneg int ExprIdToken::getExpressionId() const { @@ -495,17 +493,6 @@ static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars) } } -static void debugPrint(const ProgramMemory& pm) -{ - for (auto&& p : pm) { - if (p.first.tok) - std::cout << p.first->expressionString(); - else - std::cout << p.first.exprid; - std::cout << " => " << p.second.toString() << std::endl; - } -} - void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars) { ProgramMemory local = state; From c57b41f82f731038031e07ebb9072e138302a029 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 22 Sep 2025 13:20:18 -0500 Subject: [PATCH 9/9] Add comment --- lib/programmemory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 902992aff40..ffc97ae1509 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -482,7 +482,7 @@ void ProgramMemoryState::replace(ProgramMemory pm, const Token* origin) if (origin) for (const auto& p : pm) origins[p.first.getExpressionId()] = origin; - state.replace(std::move(pm), true); + state.replace(std::move(pm), /*skipUnknown*/ true); } static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars)