diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index e122cc670..24bfaccb9 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -507,6 +507,21 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec() } if (assignment) continue; + + // Is the dereference checked with a previous && + bool checked = false; + for (tok2 = tok1->tokAt(-2); tok2; tok2 = tok2->previous()) { + if (Token::Match(tok2, "[,(;{}]")) + break; + else if (tok2->str() == ")") + tok2 = tok2->link(); + else if (Token::Match(tok2, "%varid% &&", varid1)) { + checked = true; + break; + } + } + if (checked) + continue; } // Goto next token @@ -673,16 +688,19 @@ void CheckNullPointer::nullPointerByDeRefAndChec() if (tok1->varId() == varid) { // Don't write warning if the dereferencing is - // guarded by ?: + // guarded by ?: or && const Token *tok2 = tok1->previous(); if (tok2 && (tok2->isArithmeticalOp() || tok2->str() == "(")) { while (tok2 && !Token::Match(tok2, "[;{}?:]")) { if (tok2->str() == ")") tok2 = tok2->link(); + // guarded by && + if (tok2->varId() == varid && tok2->next()->str() == "&&") + break; tok2 = tok2->previous(); } } - if (Token::Match(tok2, "[?:]")) + if (Token::Match(tok2, "[?:]") || tok2->varId() == varid) continue; // unknown : this is set by isPointerDeRef if it is diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 5cb9922ba..c174f8f2a 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -301,6 +301,12 @@ private: "}\n"); ASSERT_EQUALS("", errout.str()); + check("void f(struct ABC *abc) {\n" + " int x = abc && a(abc->x);\n" + " if (abc) { }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + // ok to use a linked list.. check("void foo(struct ABC *abc)\n" "{\n"