diff --git a/src/checkother.cpp b/src/checkother.cpp index 8c4a9f2ae..cdcf15754 100644 --- a/src/checkother.cpp +++ b/src/checkother.cpp @@ -1029,7 +1029,7 @@ void CheckOther::nullPointer() } } - // Dereferencing a pointer and then checking if it's NULL.. + // Dereferencing a struct pointer and then checking if it's NULL.. for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next()) { if (Token::Match(tok1, "[{};] %var% = %var% . %var%")) @@ -1076,6 +1076,37 @@ void CheckOther::nullPointer() } } } + + // Dereferencing a pointer and then checking if it's NULL.. + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + if (tok->str() == "if" && Token::Match(tok->previous(), "; if ( ! %var% )")) + { + const unsigned int varid(tok->tokAt(3)->varId()); + if (varid == 0) + continue; + + for (const Token *tok1 = tok->previous(); tok1; tok1 = tok1->previous()) + { + if (tok1->varId() == varid) + { + if (tok1->previous() && tok1->previous()->str() == "*") + { + nullPointerError(tok1); + break; + } + else if (tok1->next() && tok1->next()->str() == "=") + { + break; + } + } + + else if (tok1->str() == "{" || + tok1->str() == "}") + break; + } + } + } } diff --git a/test/testother.cpp b/test/testother.cpp index dee0f6783..a2346c4e7 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -59,6 +59,7 @@ private: TEST_CASE(nullpointer1); TEST_CASE(nullpointer2); TEST_CASE(nullpointer3); // dereferencing struct and then checking if it's null + TEST_CASE(nullpointer4); TEST_CASE(oldStylePointerCast); } @@ -410,6 +411,7 @@ private: Tokenizer tokenizer; std::istringstream istr(code); tokenizer.tokenize(istr, "test.cpp"); + tokenizer.simplifyTokenList(); tokenizer.setVarId(); // Clear the error buffer.. @@ -508,6 +510,34 @@ private: ASSERT_EQUALS("", errout.str()); } + // Dereferencing a pointer and then checking if it is null + void nullpointer4() + { + // errors.. + checkNullPointer("void foo(int *p)\n" + "{\n" + " *p = 0;\n" + " if (!p)\n" + " ;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference\n", errout.str()); + + // no error + checkNullPointer("void foo(int *p)\n" + "{\n" + " if (x)\n" + " p = 0;\n" + " else\n" + " *p = 0;\n" + " if (!p)\n" + " ;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + } + + + + void checkOldStylePointerCast(const char code[]) { // Tokenize..