diff --git a/lib/exprengine.cpp b/lib/exprengine.cpp index b6a8e4c01..ac1c1b688 100644 --- a/lib/exprengine.cpp +++ b/lib/exprengine.cpp @@ -799,7 +799,7 @@ ExprEngine::ArrayValue::ArrayValue(DataBase *data, const Variable *var) } ValuePtr val; - if (var && !var->isGlobal() && !var->isStatic()) + if (var && !var->isGlobal() && !var->isStatic() && !(var->isArgument() && var->isConst())) val = std::make_shared(); else if (var && var->valueType()) { ::ValueType vt(*var->valueType()); diff --git a/test/testbughuntingchecks.cpp b/test/testbughuntingchecks.cpp index fc1f11cd4..537f214c2 100644 --- a/test/testbughuntingchecks.cpp +++ b/test/testbughuntingchecks.cpp @@ -31,6 +31,7 @@ private: void run() OVERRIDE { #ifdef USE_Z3 TEST_CASE(uninit); + TEST_CASE(uninit_function_par); TEST_CASE(ctu); #endif } @@ -56,6 +57,25 @@ private: ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that 'x' is initialized\n", errout.str()); } + void uninit_function_par() { + // non constant parameters may point at uninitialized data + // constant parameters should point at initialized data + + check("char foo(char id[]) { return id[0]; }"); + ASSERT_EQUALS("[test.cpp:1]: (error) Cannot determine that 'id[0]' is initialized\n", errout.str()); + + check("char foo(const char id[]) { return id[0]; }"); + ASSERT_EQUALS("", errout.str()); + + check("char foo(const char id[]);\n" + "void bar() { char data[10]; foo(data); }"); + TODO_ASSERT_EQUALS("error", "", errout.str()); + + check("char foo(char id[]);\n" + "void bar() { char data[10]; foo(data); }"); + ASSERT_EQUALS("", errout.str()); + } + void ctu() { check("void init(int &x) {\n" " x = 1;\n"