Fix #11776 (False positive: uninitialized variable, struct array member initialized in function) (#5165)
This commit is contained in:
parent
58dd92dd1b
commit
9a290c959f
|
@ -3105,6 +3105,10 @@ static ExprUsage getFunctionUsage(const Token* tok, int indirect, const Settings
|
|||
}
|
||||
if (!args.empty() && indirect == 0 && !addressOf)
|
||||
return ExprUsage::Used;
|
||||
} else if (ftok->isControlFlowKeyword()) {
|
||||
return ExprUsage::Used;
|
||||
} else if (ftok->str() == "{") {
|
||||
return ExprUsage::Used;
|
||||
} else {
|
||||
const bool isnullbad = settings->library.isnullargbad(ftok, argnr + 1);
|
||||
if (indirect == 0 && astIsPointer(tok) && !addressOf && isnullbad)
|
||||
|
|
|
@ -1621,6 +1621,8 @@ void CheckUninitVar::valueFlowUninit()
|
|||
if (tok->variable()) {
|
||||
bool unknown;
|
||||
const bool isarray = tok->variable()->isArray();
|
||||
if (isarray && tok->variable()->isMember())
|
||||
continue; // Todo: this is a bailout
|
||||
const bool ispointer = astIsPointer(tok) && !isarray;
|
||||
const bool deref = CheckNullPointer::isPointerDeRef(tok, unknown, mSettings);
|
||||
if (ispointer && v->indirect == 1 && !deref)
|
||||
|
@ -1633,7 +1635,7 @@ void CheckUninitVar::valueFlowUninit()
|
|||
continue;
|
||||
}
|
||||
const ExprUsage usage = getExprUsage(tok, v->indirect, mSettings);
|
||||
if (usage == ExprUsage::NotUsed)
|
||||
if (usage == ExprUsage::NotUsed || usage == ExprUsage::Inconclusive)
|
||||
continue;
|
||||
if (!v->subexpressions.empty() && usage == ExprUsage::PassedByReference)
|
||||
continue;
|
||||
|
|
|
@ -1261,7 +1261,7 @@ void timet_h(struct timespec* ptp1)
|
|||
clock_settime(clk_id2, ptp1);
|
||||
|
||||
struct timespec tp;
|
||||
// cppcheck-suppress uninitvar
|
||||
// FIXME cppcheck-suppress uninitvar
|
||||
clock_settime(CLOCK_REALTIME, &tp); // #6577 - false negative
|
||||
// cppcheck-suppress uninitvar
|
||||
clock_settime(clk_id3, &tp);
|
||||
|
|
|
@ -5268,7 +5268,7 @@ private:
|
|||
" s.x = 42;\n"
|
||||
" bar(&s);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:18]: (error) Uninitialized variable: &s.flag\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:18] -> [test.cpp:12] -> [test.cpp:8]: (warning) Uninitialized variable: s->flag\n", errout.str());
|
||||
|
||||
// Ticket #2207 - False negative
|
||||
valueFlowUninit("void foo() {\n"
|
||||
|
@ -6136,7 +6136,7 @@ private:
|
|||
" someType_t gVar;\n"
|
||||
" bar(&gVar);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:9]: (error) Uninitialized variable: &gVar\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:9] -> [test.cpp:5]: (warning) Uninitialized variable: p->flags\n", errout.str());
|
||||
|
||||
valueFlowUninit("typedef struct\n"
|
||||
"{\n"
|
||||
|
@ -6146,7 +6146,8 @@ private:
|
|||
" someType_t gVar;\n"
|
||||
" if(gVar.flags[1] == 42){}\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: gVar.flags\n", errout.str());
|
||||
// TODO : find bugs for member arrays
|
||||
TODO_ASSERT_EQUALS("[test.cpp:7]: (error) Uninitialized variable: gVar.flags\n", "", errout.str());
|
||||
|
||||
valueFlowUninit("void foo() {\n" // #10293
|
||||
" union {\n"
|
||||
|
@ -6667,7 +6668,7 @@ private:
|
|||
" foo(123, &abc);\n"
|
||||
" return abc.b;\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: &abc\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:6]: (error) Uninitialized variable: abc.b\n", errout.str());
|
||||
|
||||
valueFlowUninit("struct ABC { int a; int b; int c; };\n"
|
||||
"void foo() {\n"
|
||||
|
@ -6899,7 +6900,7 @@ private:
|
|||
" abc.a = 1;\n"
|
||||
" setabc(123, &abc);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:8]: (error) Uninitialized variables: &abc.b, &abc.c\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:3]: (warning) Uninitialized variable: abc->b\n", errout.str());
|
||||
|
||||
valueFlowUninit("struct S { int* p; };\n" // #10463
|
||||
"void f(S* in) {\n"
|
||||
|
@ -6942,6 +6943,41 @@ private:
|
|||
" if (f < s.offset + sizeof(s)) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// #11776 - function call initialises struct array member
|
||||
valueFlowUninit("typedef struct {\n"
|
||||
" int arr[1];\n"
|
||||
" int count;\n"
|
||||
"} arr_struct;\n"
|
||||
"\n"
|
||||
"void init(int *a, int b);\n"
|
||||
"\n"
|
||||
"void foo(arr_struct const *var);\n" // <- inconclusive if var->count is used
|
||||
"\n"
|
||||
"void uninitvar_FP7() {\n"
|
||||
" arr_struct my_st;\n"
|
||||
" init(my_st.arr, 12);\n" // <- assume that my_st.arr is written
|
||||
" foo(&my_st);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
valueFlowUninit("typedef struct {\n"
|
||||
" int arr[1];\n"
|
||||
" int count;\n"
|
||||
"} arr_struct;\n"
|
||||
"\n"
|
||||
"void init(int *a, int b);\n"
|
||||
"\n"
|
||||
"void foo(arr_struct const *var) {\n"
|
||||
" x = var->arr[0];\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void uninitvar_FP7() {\n"
|
||||
" arr_struct my_st;\n"
|
||||
" init(my_st.arr, 12);\n" // <- assume that my_st.arr is written
|
||||
" foo(&my_st);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void uninitvar_memberfunction() {
|
||||
|
|
Loading…
Reference in New Issue