diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index c9a0e3053..e73508cfa 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -171,6 +171,13 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown) if (parent->str() == "[" && (!parent->astParent() || parent->astParent()->str() != "&")) 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 if (firstOperand && parent->str() == "." && (!parent->astParent() || parent->astParent()->str() != "&")) { if (!parent->astParent() || parent->astParent()->str() != "(" || parent->astParent() == tok->previous()) diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 1d13cfafb..17f5785c4 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -60,6 +60,7 @@ private: TEST_CASE(nullpointer25); // #5061 TEST_CASE(nullpointer26); // #3589 TEST_CASE(nullpointer27); // #6014 + TEST_CASE(nullpointer_addressOf); // address of TEST_CASE(nullpointerSwitch); // #2626 TEST_CASE(nullpointer_cast); // #4692 TEST_CASE(nullpointer_castToVoid); // #3771 @@ -1335,6 +1336,20 @@ private: "[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 check("char *f(int x) {\n" " char *p = do_something();\n"