Skip to content

Commit

Permalink
Fix 12032: False positive: uninitialized variable, flags with same va…
Browse files Browse the repository at this point in the history
…lue (#5754)
  • Loading branch information
pfultz2 authored Dec 23, 2023
1 parent 77157a6 commit 7f0234e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 4 deletions.
32 changes: 28 additions & 4 deletions lib/programmemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1640,6 +1640,14 @@ namespace {
return *it;
}

static bool updateValue(ValueFlow::Value& v, ValueFlow::Value x)
{
const bool returnValue = !x.isUninitValue() && !x.isImpossible();
if (v.isUninitValue() || returnValue)
v = std::move(x);
return returnValue;
}

ValueFlow::Value execute(const Token* expr)
{
depth--;
Expand All @@ -1648,13 +1656,29 @@ namespace {
}};
if (depth < 0)
return unknown();
ValueFlow::Value v = executeImpl(expr);
if (!v.isUninitValue())
ValueFlow::Value v = unknown();
if (updateValue(v, executeImpl(expr)))
return v;
if (!expr)
return v;
if (expr->exprId() > 0 && pm->hasValue(expr->exprId()))
return pm->at(expr->exprId());
if (expr->exprId() > 0 && pm->hasValue(expr->exprId())) {
if (updateValue(v, pm->at(expr->exprId())))
return v;
}
// Find symbolic values
for (const ValueFlow::Value& value : expr->values()) {
if (!value.isSymbolicValue())
continue;
if (!value.isKnown())
continue;
if (value.tokvalue->exprId() > 0 && !pm->hasValue(value.tokvalue->exprId()))
continue;
ValueFlow::Value v2 = pm->at(value.tokvalue->exprId());
if (!v2.isIntValue() && value.intvalue != 0)
continue;
v2.intvalue += value.intvalue;
return v2;
}
if (const ValueFlow::Value* value = getImpossibleValue(expr))
return *value;
return v;
Expand Down
16 changes: 16 additions & 0 deletions test/testvalueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5645,6 +5645,22 @@ class TestValueFlow : public TestFixture {
values = tokenValues(code, "x <", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(0, values.size());

code = "void getX(int *p);\n"
"bool do_something();\n"
"void foo() {\n"
" int x;\n"
" bool flag;\n"
" bool success;\n"
" success = do_something();\n"
" flag = success;\n"
" if (success == true) {\n"
" getX(&x);\n"
" }\n"
" for (int i = 0; (flag == true) && (i < x); ++i) {}\n"
"}\n";
values = tokenValues(code, "x ) ; ++ i", ValueFlow::Value::ValueType::UNINIT);
ASSERT_EQUALS(0, values.size());

code = "void g(bool *result, size_t *buflen) {\n" // #12091
" if (*result && *buflen >= 5) {}\n" // <- *buflen might not be initialized
"}\n"
Expand Down

0 comments on commit 7f0234e

Please sign in to comment.