CheckNullPointer: Fix FP when x is NULL and address is calculated with expression '&x->y.z[0]'

This commit is contained in:
Daniel Marjamäki 2015-01-05 14:54:24 +01:00
parent c5467766e2
commit fe8d04e840
2 changed files with 22 additions and 0 deletions

View File

@ -171,6 +171,13 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
if (parent->str() == "[" && (!parent->astParent() || parent->astParent()->str() != "&")) if (parent->str() == "[" && (!parent->astParent() || parent->astParent()->str() != "&"))
return true; return true;
// address of member variable / array element
const Token *parent2 = parent;
while (Token::Match(parent2, "[|."))
parent2 = parent2->astParent();
if (parent2 != parent && parent2 && parent2->str() == "&" && !parent2->astOperand2())
return false;
// read/write member variable // read/write member variable
if (firstOperand && parent->str() == "." && (!parent->astParent() || parent->astParent()->str() != "&")) { if (firstOperand && parent->str() == "." && (!parent->astParent() || parent->astParent()->str() != "&")) {
if (!parent->astParent() || parent->astParent()->str() != "(" || parent->astParent() == tok->previous()) if (!parent->astParent() || parent->astParent()->str() != "(" || parent->astParent() == tok->previous())

View File

@ -60,6 +60,7 @@ private:
TEST_CASE(nullpointer25); // #5061 TEST_CASE(nullpointer25); // #5061
TEST_CASE(nullpointer26); // #3589 TEST_CASE(nullpointer26); // #3589
TEST_CASE(nullpointer27); // #6014 TEST_CASE(nullpointer27); // #6014
TEST_CASE(nullpointer_addressOf); // address of
TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointerSwitch); // #2626
TEST_CASE(nullpointer_cast); // #4692 TEST_CASE(nullpointer_cast); // #4692
TEST_CASE(nullpointer_castToVoid); // #3771 TEST_CASE(nullpointer_castToVoid); // #3771
@ -1335,6 +1336,20 @@ private:
"[test.cpp:3]: (error) Null pointer dereference\n", errout.str()); "[test.cpp:3]: (error) Null pointer dereference\n", errout.str());
} }
void nullpointer_addressOf() { // address of
check("void f() {\n"
" struct X *x = 0;\n"
" if (addr == &x->y) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
check("void f() {\n"
" struct X *x = 0;\n"
" if (addr == &x->y.z[0]) {}\n"
"}");
ASSERT_EQUALS("", errout.str());
}
void nullpointerSwitch() { // #2626 void nullpointerSwitch() { // #2626
check("char *f(int x) {\n" check("char *f(int x) {\n"
" char *p = do_something();\n" " char *p = do_something();\n"