diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index 388f4149c..f0ad91118 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -2567,8 +2567,15 @@ static ExprEngine::ValuePtr createVariableValue(const Variable &var, Data &data) data.addConstraints(value, var.nameToken()); return value; } - if (valueType->type == ValueType::Type::RECORD) - return createStructVal(valueType->typeScope, var.isLocal() && !var.isStatic(), data); + if (valueType->type == ValueType::Type::RECORD) { + bool init = true; + if (var.isLocal() && !var.isStatic()) { + init = valueType->typeScope && + valueType->typeScope->definedType && + valueType->typeScope->definedType->needInitialization != Type::NeedInitialization::False; + } + return createStructVal(valueType->typeScope, init, data); + } if (valueType->smartPointerType) { auto structValue = createStructVal(valueType->smartPointerType->classScope, var.isLocal() && !var.isStatic(), data); auto size = std::make_shared(data.getNewSymbolName(), 1, ~0UL); diff --git a/test/testbughuntingchecks.cpp b/test/testbughuntingchecks.cpp index bfb62e985..392991b31 100644 --- a/test/testbughuntingchecks.cpp +++ b/test/testbughuntingchecks.cpp @@ -39,6 +39,7 @@ private: TEST_CASE(uninit_array); TEST_CASE(uninit_function_par); TEST_CASE(uninit_malloc); + TEST_CASE(uninit_struct); TEST_CASE(ctu); #endif } @@ -98,6 +99,17 @@ private: ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that '*p' is initialized\n", errout.str()); } + void uninit_struct() { + // Assume that constructors initialize all members + // TODO whole program analysis + check("struct Data { Data(); int x; }\n" + "void foo() {\n" + " Data data;\n" + " x = data.x;\n" + "}"); + ASSERT_EQUALS("", errout.str()); + } + void ctu() { check("void init(int &x) {\n" " x = 1;\n"