Fix 12032: False positive: uninitialized variable, flags with same value (#5754)
This commit is contained in:
parent
77157a678a
commit
7f0234e7d5
|
@ -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--;
|
||||
|
@ -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;
|
||||
|
|
|
@ -5645,6 +5645,22 @@ private:
|
|||
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"
|
||||
|
|
Loading…
Reference in New Issue