Fixed #3220 (False positive: possible null pointer dereference: 'SwDoc *pDoc = NULL; pDoc->do_something();')

This commit is contained in:
Daniel Marjamäki 2011-10-18 19:34:14 +02:00
parent 03ff25f152
commit 3d18fdfa3f
3 changed files with 56 additions and 17 deletions

View File

@ -104,6 +104,10 @@ public:
std::cout << errmsg.toXML(true, 1) << std::endl;
}
bool inconclusiveFlag() const {
return _settings && _settings->inconclusive;
}
protected:
const std::string _name;
const Tokenizer * const _tokenizer;

View File

@ -184,8 +184,13 @@ bool CheckNullPointer::isPointerDeRef(const Token *tok, bool &unknown)
if (Token::Match(tok->tokAt(-3), "!!sizeof [;{}=+-/(,] * %var%") && Token::Match(tok->tokAt(-3), "!!decltype [;{}=+-/(,] * %var%"))
return true;
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;
// read/write member variable
if (!Token::simpleMatch(tok->tokAt(-2), "& (") && !Token::Match(tok->tokAt(-2), "sizeof|decltype (") && tok->strAt(-1) != "&" && tok->strAt(-1) != "&&" && Token::Match(tok->next(), ". %var%")) {
if (tok->strAt(3) != "(")
return true;
unknown = true;
return false;
}
if (Token::Match(tok->previous(), "[;{}=+-/(,] %var% ["))
return true;
@ -299,6 +304,11 @@ void CheckNullPointer::nullPointerAfterLoop()
if (CheckNullPointer::isPointerDeRef(tok2, unknown)) {
nullPointerError(tok2, varname, tok->linenr(), inconclusive);
}
else if (unknown && _settings->inconclusive) {
nullPointerError(tok2, varname, tok->linenr(), true);
}
break;
}
}
@ -1050,6 +1060,8 @@ private:
setnull(checks, tok.varId());
else if (CheckNullPointer::isPointerDeRef(&tok, unknown))
dereference(checks, &tok);
else if (unknown && owner->inconclusiveFlag())
dereference(checks, &tok);
else
// TODO: Report debug warning that it's unknown if a
// pointer is dereferenced

View File

@ -87,15 +87,22 @@ private:
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 3\n", errout.str());
// #2681
check("void foo(const Token *tok)\n"
"{\n"
" while (tok && tok->str() == \"=\")\n"
" tok = tok->next();\n"
"\n"
" if (tok->str() != \";\")\n"
" ;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:6]: (error) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 3\n", errout.str());
{
const char code[] = "void foo(const Token *tok)\n"
"{\n"
" while (tok && tok->str() == \"=\")\n"
" tok = tok->next();\n"
"\n"
" if (tok->str() != \";\")\n"
" ;\n"
"}\n";
check(code, false); // inconclusive=false => no error
ASSERT_EQUALS("", errout.str());
check(code, true); // inconclusive=true => error
ASSERT_EQUALS("[test.cpp:6]: (error) Possible null pointer dereference: tok - otherwise it is redundant to check if tok is null at line 3\n", errout.str());
}
check("void foo()\n"
"{\n"
@ -715,12 +722,21 @@ private:
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
check("static void foo(int x)\n"
"{\n"
" Foo<int> *abc = 0;\n"
" abc->a();\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: abc\n", errout.str());
{
const char code[] = "static void foo(int x)\n"
"{\n"
" Foo<int> *abc = 0;\n"
" abc->a();\n"
"}\n";
// inconclusive=false => no error
check(code,false);
ASSERT_EQUALS("", errout.str());
// inconclusive=true => error
check(code, true);
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: abc\n", errout.str());
}
check("static void foo()\n"
"{\n"
@ -899,6 +915,13 @@ private:
" int x = &fred->x;\n"
"}");
ASSERT_EQUALS("", errout.str());
// ticket #3220: calling member function
check("void f() {\n"
" Fred *fred = NULL;\n"
" fred->do_something();\n"
"}");
ASSERT_EQUALS("", errout.str());
}
// Ticket #2350