diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 919ce232d..da115e642 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -411,7 +411,7 @@ void CheckNullPointer::nullConstantDereference() nullPointerError(tok); else if (Token::Match(tok->previous(), "!!. %name% (") && (tok->previous()->str() != "::" || tok->strAt(-2) == "std")) { - if (Token::simpleMatch(tok->tokAt(2), "0 )") && tok->varId()) { // constructor call + if (Token::Match(tok->tokAt(2), "0|NULL|nullptr )") && tok->varId()) { // constructor call const Variable *var = tok->variable(); if (var && !var->isPointer() && !var->isArray() && var->isStlStringType()) nullPointerError(tok); @@ -421,15 +421,15 @@ void CheckNullPointer::nullConstantDereference() // is one of the var items a NULL pointer? for (std::list::const_iterator it = var.begin(); it != var.end(); ++it) { - if (Token::Match(*it, "0|NULL [,)]")) { + if (Token::Match(*it, "0|NULL|nullptr [,)]")) { nullPointerError(*it); } } } - } else if (Token::Match(tok, "std :: string|wstring ( 0 )")) + } else if (Token::Match(tok, "std :: string|wstring ( 0|NULL|nullptr )")) nullPointerError(tok); - else if (Token::simpleMatch(tok->previous(), ">> 0")) { // Only checking input stream operations is safe here, because otherwise 0 can be an integer as well + else if (Token::Match(tok->previous(), ">> 0|NULL|nullptr")) { // Only checking input stream operations is safe here, because otherwise 0 can be an integer as well const Token* tok2 = tok->previous(); // Find start of statement for (; tok2; tok2 = tok2->previous()) { if (Token::Match(tok2->previous(), ";|{|}|:|(")) @@ -448,13 +448,13 @@ void CheckNullPointer::nullConstantDereference() const Variable *ovar = nullptr; const Token *tokNull = nullptr; - if (Token::Match(tok, "0 ==|!=|>|>=|<|<= %var%")) { + if (Token::Match(tok, "0|NULL|nullptr ==|!=|>|>=|<|<= %var%")) { if (!Token::Match(tok->tokAt(3),".|[")) { ovar = tok->tokAt(2)->variable(); tokNull = tok; } - } else if (Token::Match(tok, "%var% ==|!=|>|>=|<|<= 0") || - Token::Match(tok, "%var% =|+ 0 )|]|,|;|+")) { + } else if (Token::Match(tok, "%var% ==|!=|>|>=|<|<= 0|NULL|nullptr") || + Token::Match(tok, "%var% =|+ 0|NULL|nullptr )|]|,|;|+")) { ovar = tok->variable(); tokNull = tok->tokAt(2); } diff --git a/test/testnullpointer.cpp b/test/testnullpointer.cpp index 50a3126a5..6c367b67d 100644 --- a/test/testnullpointer.cpp +++ b/test/testnullpointer.cpp @@ -2008,6 +2008,30 @@ private: "[test.cpp:12]: (error) Possible null pointer dereference: p\n"*/ , errout.str()); + check("void f(std::string s1) {\n" + " s1 = nullptr;\n" + " std::string s2 = nullptr;\n" + " std::string s3(nullptr);\n" + " foo(std::string(nullptr));\n" + "}", true); + ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n" + "[test.cpp:3]: (error) Null pointer dereference\n" + "[test.cpp:4]: (error) Null pointer dereference\n" + "[test.cpp:5]: (error) Null pointer dereference\n" + , errout.str()); + + check("void f(std::string s1) {\n" + " s1 = NULL;\n" + " std::string s2 = NULL;\n" + " std::string s3(NULL);\n" + " foo(std::string(NULL));\n" + "}", true); + ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n" + "[test.cpp:3]: (error) Null pointer dereference\n" + "[test.cpp:4]: (error) Null pointer dereference\n" + "[test.cpp:5]: (error) Null pointer dereference\n" + , errout.str()); + check("void f(std::string s1, const std::string& s2, const std::string* s3) {\n" " void* p = 0;\n" " if (x) { return; }\n" @@ -2081,10 +2105,14 @@ private: " foo(0, \"\");\n" " foo(0, 0);\n" " foo(var, 0);\n" + " foo(var, NULL);\n" + " foo(var, nullptr);\n" " foo(0, var);\n" "}"); ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference\n" - "[test.cpp:5]: (error) Null pointer dereference\n", errout.str()); + "[test.cpp:5]: (error) Null pointer dereference\n" + "[test.cpp:6]: (error) Null pointer dereference\n" + "[test.cpp:7]: (error) Null pointer dereference\n", errout.str()); } void nullpointerStdStream() {