From bc3507118d1a3e6ce49c2a657c1bf37735477505 Mon Sep 17 00:00:00 2001 From: Martin Exner Date: Sun, 3 Apr 2011 21:06:42 +0200 Subject: [PATCH] Fixed #2696 (False positive nullpointer) --- lib/checknullpointer.cpp | 8 ++++---- test/testnullpointer.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) 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