Skip to content

Commit 35dc425

Browse files
authored
Fix 13930: False positive: valueflow and other variable (#7827)
1 parent 4d04f41 commit 35dc425

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

lib/programmemory.cpp

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -227,14 +227,19 @@ bool ProgramMemory::empty() const
227227
}
228228

229229
// NOLINTNEXTLINE(performance-unnecessary-value-param) - technically correct but we are moving the given values
230-
void ProgramMemory::replace(ProgramMemory pm)
230+
void ProgramMemory::replace(ProgramMemory pm, bool skipUnknown)
231231
{
232232
if (pm.empty())
233233
return;
234234

235235
copyOnWrite();
236236

237237
for (auto&& p : (*pm.mValues)) {
238+
if (skipUnknown) {
239+
auto it = mValues->find(p.first);
240+
if (it != mValues->end() && it->second.isUninitValue())
241+
continue;
242+
}
238243
(*mValues)[p.first] = std::move(p.second);
239244
}
240245
}
@@ -438,7 +443,8 @@ static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok
438443
if (!setvar) {
439444
if (!pm.hasValue(vartok->exprId())) {
440445
const Token* valuetok = tok2->astOperand2();
441-
pm.setValue(vartok, execute(valuetok, pm, settings));
446+
ProgramMemory local = state;
447+
pm.setValue(vartok, execute(valuetok, local, settings));
442448
}
443449
}
444450
} else if (Token::simpleMatch(tok2, ")") && tok2->link() &&
@@ -519,7 +525,7 @@ void ProgramMemoryState::replace(ProgramMemory pm, const Token* origin)
519525
if (origin)
520526
for (const auto& p : pm)
521527
origins[p.first.getExpressionId()] = origin;
522-
state.replace(std::move(pm));
528+
state.replace(std::move(pm), /*skipUnknown*/ true);
523529
}
524530

525531
static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars)
@@ -532,13 +538,14 @@ static void addVars(ProgramMemory& pm, const ProgramMemory::Map& vars)
532538

533539
void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& vars)
534540
{
535-
ProgramMemory pm = state;
536-
addVars(pm, vars);
537-
fillProgramMemoryFromConditions(pm, tok, settings);
538-
ProgramMemory local = pm;
541+
ProgramMemory local = state;
542+
addVars(local, vars);
543+
fillProgramMemoryFromConditions(local, tok, settings);
544+
ProgramMemory pm;
539545
fillProgramMemoryFromAssignments(pm, tok, settings, local, vars);
540-
addVars(pm, vars);
541-
replace(std::move(pm), tok);
546+
local.replace(std::move(pm));
547+
addVars(local, vars);
548+
replace(std::move(local), tok);
542549
}
543550

544551
void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty)

lib/programmemory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ struct CPPCHECKLIB ProgramMemory {
134134

135135
bool empty() const;
136136

137-
void replace(ProgramMemory pm);
137+
void replace(ProgramMemory pm, bool skipUnknown = false);
138138

139139
Map::const_iterator begin() const {
140140
return mValues->cbegin();

test/testuninitvar.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6588,6 +6588,23 @@ class TestUninitVar : public TestFixture {
65886588
" return c.front();\n"
65896589
"}\n");
65906590
ASSERT_EQUALS("[test.cpp:8:12]: (error) Uninitialized variable: c [uninitvar]\n", errout_str());
6591+
6592+
// #13930
6593+
valueFlowUninit("extern int32_t g_items[10U];\n"
6594+
"uint16_t write_item(uint8_t n);\n"
6595+
"uint16_t write_item(uint8_t n) {\n"
6596+
" int32_t *p_item = NULL;\n"
6597+
" uint16_t ret;\n"
6598+
" ret = 0U;\n"
6599+
" if (n < 10U)\n"
6600+
" p_item = &g_items[n];\n"
6601+
" else\n"
6602+
" ret = 1U;\n"
6603+
" if (ret == 0U) \n"
6604+
" *p_item = 5;\n"
6605+
" return ret;\n"
6606+
"}\n");
6607+
ASSERT_EQUALS("", errout_str());
65916608
}
65926609

65936610
void valueFlowUninitBreak() { // Do not show duplicate warnings about the same uninitialized value

0 commit comments

Comments
 (0)