diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 9a3056636..32238579f 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -133,10 +133,10 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown) unknown = false; // Dereferencing pointer.. - if (Token::Match(tok->tokAt(-3), "!!sizeof [;{}=+-/(,] * %var%")) + if (Token::Match(tok->tokAt(-3), "!!sizeof [;{}=+-/(,] * %var%") && Token::Match(tok->tokAt(-3), "!!decltype [;{}=+-/(,] * %var%")) return true; - if (!Token::simpleMatch(tok->tokAt(-2), "& (") && tok->strAt(-1) != "&" && tok->strAt(-1) != "&&" && Token::Match(tok->next(), ". %var%")) + if (!Token::simpleMatch(tok->tokAt(-2), "& (") && !Token::Match(tok->tokAt(-2), "sizeof|decltype (") && tok->strAt(-1) != "&" && tok->strAt(-1) != "&&" && Token::Match(tok->next(), ". %var%")) return true; if (Token::Match(tok->previous(), "[;{}=+-/(,] %var% [")) @@ -376,8 +376,8 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec() tok1 = tok1->tokAt(3); } - // dereference in function call - else if (Token::Match(tok1->tokAt(-2), "%var% ( %var% . %var%") || + // dereference in function call (but not sizeof|decltype) + else if ((Token::Match(tok1->tokAt(-2), "%var% ( %var% . %var%") && !Token::Match(tok1->tokAt(-2), "sizeof|decltype ( %var% . %var%")) || Token::Match(tok1->previous(), ", %var% . %var%")) { // Is the function return value taken by the pointer? diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 413556fb1..af6091457 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -1047,6 +1047,45 @@ private: " }\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #2696 - false positives nr 1 + check("void f()\n" + "{\n" + " struct foo *pFoo = NULL;\n" + " size_t len;\n" + "\n" + " len = sizeof(*pFoo) - sizeof(pFoo->data);\n" + "\n" + " if (pFoo)\n" + " bar();\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + // #2696 - false positives nr 2 + check("void f()\n" + "{\n" + " struct foo *pFoo = NULL;\n" + " size_t len;\n" + "\n" + " while (pFoo)\n" + " pFoo = pFoo->next;\n" + "\n" + " len = sizeof(pFoo->data);\n" + "}"); + ASSERT_EQUALS("", errout.str()); + + // #2696 - false positives nr 3 + check("void f()\n" + "{\n" + " struct foo *pFoo = NULL;\n" + " size_t len;\n" + "\n" + " while (pFoo)\n" + " pFoo = pFoo->next;\n" + "\n" + " len = decltype(*pFoo);\n" + "}"); + ASSERT_EQUALS("", errout.str()); } // Test CheckNullPointer::nullConstantDereference