From f29733287c1ea9c5df2ebe9cda6710ad5181877a Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 16 Sep 2025 14:30:20 -0500 Subject: [PATCH 1/2] Fix 14137: False positive: uninitvar when using an assert before loop --- lib/programmemory.cpp | 9 +++++++++ test/testuninitvar.cpp | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 86d5e35273d..aabc964708a 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -441,6 +441,15 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok pm.setValue(vartok, execute(valuetok, pm, settings)); } } + } else if (Token::simpleMatch(tok2, ")") && tok2->link() && Token::Match(tok2->link()->previous(), "assert|ASSERT ( !!)")) { + const Token* cond = tok2->link()->astOperand2(); + if(!conditionIsTrue(cond, state, settings)) { + // TODO: change to assert when we can propagate the assert, for now just bail + if(conditionIsFalse(cond, state, settings)) + return; + programMemoryParseCondition(pm, cond, nullptr, settings, true); + } + tok2 = tok2->link()->previous(); } else if (tok2->exprId() > 0 && Token::Match(tok2, ".|(|[|*|%var%") && !pm.hasValue(tok2->exprId()) && isVariableChanged(tok2, 0, settings)) { pm.setUnknown(tok2); diff --git a/test/testuninitvar.cpp b/test/testuninitvar.cpp index dfdc048b4f9..540c865a8e4 100644 --- a/test/testuninitvar.cpp +++ b/test/testuninitvar.cpp @@ -7667,6 +7667,16 @@ class TestUninitVar : public TestFixture { " }\n" "}\n"); ASSERT_EQUALS("[test.cpp:3:24]: (error) Uninitialized variable: b [uninitvar]\n", errout_str()); + + // #14137 + valueFlowUninit("int f(int n) {\n" + " int x;\n" + " assert(n > 0);\n" + " for(int i=0;i Date: Tue, 16 Sep 2025 14:31:03 -0500 Subject: [PATCH 2/2] Format --- lib/programmemory.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index aabc964708a..a895fae3d13 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -441,11 +441,12 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok pm.setValue(vartok, execute(valuetok, pm, settings)); } } - } else if (Token::simpleMatch(tok2, ")") && tok2->link() && Token::Match(tok2->link()->previous(), "assert|ASSERT ( !!)")) { + } else if (Token::simpleMatch(tok2, ")") && tok2->link() && + Token::Match(tok2->link()->previous(), "assert|ASSERT ( !!)")) { const Token* cond = tok2->link()->astOperand2(); - if(!conditionIsTrue(cond, state, settings)) { + if (!conditionIsTrue(cond, state, settings)) { // TODO: change to assert when we can propagate the assert, for now just bail - if(conditionIsFalse(cond, state, settings)) + if (conditionIsFalse(cond, state, settings)) return; programMemoryParseCondition(pm, cond, nullptr, settings, true); }