diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index acf2f642e..f3cf18706 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -367,6 +367,15 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec() skipvar.insert(tok1->varId()); continue; } + else if (Token::Match(tok1, "( ! %var% ||") || + Token::Match(tok1, "( %var% &&")) + { + tok1 = tok1->next(); + if (tok1->str() == "!") + tok1 = tok1->next(); + skipvar.insert(tok1->varId()); + continue; + } /** * @todo There are lots of false negatives here. A dereference @@ -564,6 +573,10 @@ void CheckNullPointer::nullPointerByDeRefAndChec() if (Token::Match(tok1->link()->previous(), "while ( %varid%", varid)) break; + if (Token::Match(tok1->link(), "( ! %varid% ||", varid) || + Token::Match(tok1->link(), "( %varid% &&", varid)) + break; + if (Token::simpleMatch(tok1->link()->previous(), "sizeof (")) { tok1 = tok1->link()->previous(); diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 9a01034ab..0a5f7ebda 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -385,6 +385,13 @@ private: " }\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #3128 + check("void f(ABC *abc) {\n" + " x(!abc || y(abc->a));\n" + " if (abc) {}\n" + "}"); + ASSERT_EQUALS("", errout.str()); } // Dereferencing a pointer and then checking if it is null @@ -524,6 +531,19 @@ private: "}"); ASSERT_EQUALS("", errout.str()); + // #3128 - false positive + check("void f(int *p) {\n" + " assert(!p || (*p<=6));\n" + " if (p) { *p = 0; }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + check("void f(int *p) {\n" + " assert(p && (*p<=6));\n" + " if (p) { *p = 0; }\n" + "}"); + ASSERT_EQUALS("", errout.str()); + check("void foo(x *p)\n" "{\n" " p = p->next;\n"