Skip to content

Commit 34b5e0c

Browse files
committed
Fixed danmar#6873 (False positive uninitvar - variable initialized via pointer)
1 parent 5fef7cc commit 34b5e0c

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

lib/checkuninitvar.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,8 +487,12 @@ bool CheckUninitVar::checkScopeForVariable(const Token *tok, const Variable& var
487487
const Token *end = tok->next()->link();
488488

489489
// If address of variable is taken in the block then bail out
490-
if (Token::findmatch(tok->tokAt(2), "& %varid%", end, var.declarationId()))
490+
if (var.isPointer() || var.isArray()) {
491+
if (Token::findmatch(tok->tokAt(2), "%varid%", end, var.declarationId()))
492+
return true;
493+
} else if (Token::findmatch(tok->tokAt(2), "& %varid%", end, var.declarationId())) {
491494
return true;
495+
}
492496

493497
// Skip block
494498
tok = end;

test/testuninitvar.cpp

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class TestUninitVar : public TestFixture {
4545
TEST_CASE(uninitvar_switch); // handling switch
4646
TEST_CASE(uninitvar_references); // references
4747
TEST_CASE(uninitvar_return); // return
48+
TEST_CASE(uninitvar_assign); // = {..}
4849
TEST_CASE(uninitvar_strncpy); // strncpy doesn't always null-terminate
4950
TEST_CASE(func_uninit_var); // analyse function calls for: 'int a(int x) { return x+x; }'
5051
TEST_CASE(func_uninit_pointer); // analyse function calls for: 'void a(int *p) { *p = 0; }'
@@ -486,16 +487,6 @@ class TestUninitVar : public TestFixture {
486487
"}");
487488
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: s\n", errout.str());
488489

489-
// #1533
490-
checkUninitVar("char a()\n"
491-
"{\n"
492-
" char key;\n"
493-
" struct A msg = { .buf = {&key} };\n"
494-
" init(&msg);\n"
495-
" key++;\n"
496-
"}");
497-
ASSERT_EQUALS("", errout.str());
498-
499490
checkUninitVar("void foo()\n"
500491
"{\n"
501492
" char *buf = malloc(100);\n"
@@ -1892,6 +1883,18 @@ class TestUninitVar : public TestFixture {
18921883
"}");
18931884
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: i\n", errout.str());
18941885
}
1886+
}
1887+
1888+
void uninitvar_assign() { // = { .. }
1889+
// #1533
1890+
checkUninitVar("char a()\n"
1891+
"{\n"
1892+
" char key;\n"
1893+
" struct A msg = { .buf = {&key} };\n"
1894+
" init(&msg);\n"
1895+
" key++;\n"
1896+
"}");
1897+
ASSERT_EQUALS("", errout.str());
18951898

18961899
// Ticket #5660 - False positive
18971900
checkUninitVar("int f() {\n"
@@ -1901,6 +1904,25 @@ class TestUninitVar : public TestFixture {
19011904
" return result;\n"
19021905
"}");
19031906
ASSERT_EQUALS("", errout.str());
1907+
1908+
// #6873
1909+
checkUninitVar("int f() {\n"
1910+
" char a[10];\n"
1911+
" char *b[] = {a};\n"
1912+
" foo(b);\n"
1913+
" return atoi(a);\n"
1914+
"}");
1915+
ASSERT_EQUALS("", errout.str());
1916+
1917+
// = { .. }
1918+
checkUninitVar("int f() {\n"
1919+
" int a;\n"
1920+
" int *p[] = { &a };\n"
1921+
" *p[0] = 0;\n"
1922+
" return a;\n"
1923+
"}");
1924+
ASSERT_EQUALS("", errout.str());
1925+
19041926
}
19051927

19061928
// strncpy doesn't always null-terminate..
@@ -2139,15 +2161,6 @@ class TestUninitVar : public TestFixture {
21392161
"}");
21402162
ASSERT_EQUALS("", errout.str());
21412163

2142-
// = { .. }
2143-
checkUninitVar("int f() {\n"
2144-
" int a;\n"
2145-
" int *p[] = { &a };\n"
2146-
" *p[0] = 0;\n"
2147-
" return a;\n"
2148-
"}");
2149-
ASSERT_EQUALS("", errout.str());
2150-
21512164
// = ({ .. })
21522165
checkUninitVar("void f() {\n"
21532166
" int x = ({ 1 + 2; });\n"

0 commit comments

Comments
 (0)