Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion lib/checkuninitvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion test/cfg/posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
46 changes: 41 additions & 5 deletions test/testuninitvar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5268,7 +5268,7 @@ class TestUninitVar : public TestFixture {
" 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"
Expand Down Expand Up @@ -6136,7 +6136,7 @@ class TestUninitVar : public TestFixture {
" 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"
Expand All @@ -6146,7 +6146,8 @@ class TestUninitVar : public TestFixture {
" 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"
Expand Down Expand Up @@ -6667,7 +6668,7 @@ class TestUninitVar : public TestFixture {
" 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"
Expand Down Expand Up @@ -6899,7 +6900,7 @@ class TestUninitVar : public TestFixture {
" 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"
Expand Down Expand Up @@ -6942,6 +6943,41 @@ class TestUninitVar : public TestFixture {
" 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() {
Expand Down