Fixed handling of NULL and nullptr in CheckNullPointer

This commit is contained in:
PKEuS 2017-02-24 19:44:28 +01:00
parent b08f99a082
commit de86d40c97
2 changed files with 36 additions and 8 deletions

View File

@ -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 Token *>::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);
}

View File

@ -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() {