Fixed #6169 (False positive: passing uninitialized struct buffer member to strncpy)
This commit is contained in:
parent
cafddcb109
commit
bbbe2c1b94
|
@ -1673,6 +1673,17 @@ bool CheckUninitVar::isVariableUsage(const Token *vartok, bool pointer, bool all
|
||||||
|
|
||||||
// Accessing Rvalue member using "." or "->"
|
// Accessing Rvalue member using "." or "->"
|
||||||
if (vartok->strAt(1) == "." && vartok->strAt(-1) != "&") {
|
if (vartok->strAt(1) == "." && vartok->strAt(-1) != "&") {
|
||||||
|
// Is struct member passed to function?
|
||||||
|
if (!pointer && Token::Match(vartok->previous(), "[,(] %var% . %var%")) {
|
||||||
|
// TODO: there are FN currently:
|
||||||
|
// - should only return false if struct member is (or might be) array.
|
||||||
|
// - should only return false if function argument is (or might be) non-const pointer or reference
|
||||||
|
const Token *tok2 = vartok->next();
|
||||||
|
while (Token::Match(tok2,". %var%"))
|
||||||
|
tok2 = tok2->tokAt(2);
|
||||||
|
if (Token::Match(tok2, "[,)]"))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
bool assignment = false;
|
bool assignment = false;
|
||||||
const Token* parent = vartok->astParent();
|
const Token* parent = vartok->astParent();
|
||||||
while (parent) {
|
while (parent) {
|
||||||
|
|
|
@ -2947,6 +2947,70 @@ private:
|
||||||
"}\n", "test.c");
|
"}\n", "test.c");
|
||||||
ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.b\n", errout.str());
|
ASSERT_EQUALS("[test.c:5]: (error) Uninitialized struct member: ab.b\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" static void f() { }\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; element->f();\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" static void f() { }\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; (*element).f();\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" static int v;\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; element->v;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" static int v;\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; (*element).v;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" void f() { }\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; element->f();\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" void f() { }\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; (*element).f();\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" int v;\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; element->v;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("class Element {\n"
|
||||||
|
" int v;\n"
|
||||||
|
"};\n"
|
||||||
|
"void test() {\n"
|
||||||
|
" Element *element; (*element).v;\n"
|
||||||
|
"}");
|
||||||
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar2("struct AB { int a; int b; };\n" // pass struct member by address
|
checkUninitVar2("struct AB { int a; int b; };\n" // pass struct member by address
|
||||||
"void f(void) {\n"
|
"void f(void) {\n"
|
||||||
" struct AB ab;\n"
|
" struct AB ab;\n"
|
||||||
|
@ -2964,6 +3028,27 @@ private:
|
||||||
"}\n", "test.c");
|
"}\n", "test.c");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
{
|
||||||
|
checkUninitVar2("void f(void) {\n"
|
||||||
|
" struct AB ab;\n"
|
||||||
|
" strcpy(ab.a, STR);\n"
|
||||||
|
"}\n", "test.c");
|
||||||
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("void f(void) {\n"
|
||||||
|
" struct AB ab;\n"
|
||||||
|
" strcpy(x, ab.a);\n"
|
||||||
|
"}\n", "test.c");
|
||||||
|
TODO_ASSERT_EQUALS("error", "", errout.str());
|
||||||
|
|
||||||
|
checkUninitVar2("struct AB { int a; };\n"
|
||||||
|
"void f(void) {\n"
|
||||||
|
" struct AB ab;\n"
|
||||||
|
" dosomething(ab.a);\n"
|
||||||
|
"}\n", "test.c");
|
||||||
|
TODO_ASSERT_EQUALS("error","", errout.str());
|
||||||
|
}
|
||||||
|
|
||||||
checkUninitVar2("struct AB { int a; int b; };\n"
|
checkUninitVar2("struct AB { int a; int b; };\n"
|
||||||
"void do_something(const struct AB ab);\n"
|
"void do_something(const struct AB ab);\n"
|
||||||
"void f(void) {\n"
|
"void f(void) {\n"
|
||||||
|
@ -3163,70 +3248,6 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: ptr3\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: ptr3\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" static void f() { }\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; element->f();\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" static void f() { }\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; (*element).f();\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" static int v;\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; element->v;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" static int v;\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; (*element).v;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" void f() { }\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; element->f();\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" void f() { }\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; (*element).f();\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" int v;\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; element->v;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("class Element {\n"
|
|
||||||
" int v;\n"
|
|
||||||
"};\n"
|
|
||||||
"void test() {\n"
|
|
||||||
" Element *element; (*element).v;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
|
||||||
|
|
||||||
checkUninitVar2("void f() {\n" // #4911 - bad simplification => don't crash
|
checkUninitVar2("void f() {\n" // #4911 - bad simplification => don't crash
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
" do { a=do_something() } while (a);\n"
|
" do { a=do_something() } while (a);\n"
|
||||||
|
|
Loading…
Reference in New Issue