Fixed #3220 (False positive: possible null pointer dereference: 'SwDoc *pDoc = NULL; pDoc->do_something();')
This commit is contained in:
parent
03ff25f152
commit
3d18fdfa3f
|
@ -104,6 +104,10 @@ public:
|
||||||
std::cout << errmsg.toXML(true, 1) << std::endl;
|
std::cout << errmsg.toXML(true, 1) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool inconclusiveFlag() const {
|
||||||
|
return _settings && _settings->inconclusive;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const std::string _name;
|
const std::string _name;
|
||||||
const Tokenizer * const _tokenizer;
|
const Tokenizer * const _tokenizer;
|
||||||
|
|
|
@ -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%"))
|
if (Token::Match(tok->tokAt(-3), "!!sizeof [;{}=+-/(,] * %var%") && Token::Match(tok->tokAt(-3), "!!decltype [;{}=+-/(,] * %var%"))
|
||||||
return true;
|
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%"))
|
// read/write member variable
|
||||||
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%")) {
|
||||||
|
if (tok->strAt(3) != "(")
|
||||||
|
return true;
|
||||||
|
unknown = true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (Token::Match(tok->previous(), "[;{}=+-/(,] %var% ["))
|
if (Token::Match(tok->previous(), "[;{}=+-/(,] %var% ["))
|
||||||
return true;
|
return true;
|
||||||
|
@ -299,6 +304,11 @@ void CheckNullPointer::nullPointerAfterLoop()
|
||||||
if (CheckNullPointer::isPointerDeRef(tok2, unknown)) {
|
if (CheckNullPointer::isPointerDeRef(tok2, unknown)) {
|
||||||
nullPointerError(tok2, varname, tok->linenr(), inconclusive);
|
nullPointerError(tok2, varname, tok->linenr(), inconclusive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (unknown && _settings->inconclusive) {
|
||||||
|
nullPointerError(tok2, varname, tok->linenr(), true);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1050,6 +1060,8 @@ private:
|
||||||
setnull(checks, tok.varId());
|
setnull(checks, tok.varId());
|
||||||
else if (CheckNullPointer::isPointerDeRef(&tok, unknown))
|
else if (CheckNullPointer::isPointerDeRef(&tok, unknown))
|
||||||
dereference(checks, &tok);
|
dereference(checks, &tok);
|
||||||
|
else if (unknown && owner->inconclusiveFlag())
|
||||||
|
dereference(checks, &tok);
|
||||||
else
|
else
|
||||||
// TODO: Report debug warning that it's unknown if a
|
// TODO: Report debug warning that it's unknown if a
|
||||||
// pointer is dereferenced
|
// pointer is dereferenced
|
||||||
|
|
|
@ -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());
|
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
|
// #2681
|
||||||
check("void foo(const Token *tok)\n"
|
{
|
||||||
"{\n"
|
const char code[] = "void foo(const Token *tok)\n"
|
||||||
" while (tok && tok->str() == \"=\")\n"
|
"{\n"
|
||||||
" tok = tok->next();\n"
|
" while (tok && tok->str() == \"=\")\n"
|
||||||
"\n"
|
" tok = tok->next();\n"
|
||||||
" if (tok->str() != \";\")\n"
|
"\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());
|
"}\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"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -715,12 +722,21 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference\n", errout.str());
|
||||||
|
|
||||||
check("static void foo(int x)\n"
|
{
|
||||||
"{\n"
|
const char code[] = "static void foo(int x)\n"
|
||||||
" Foo<int> *abc = 0;\n"
|
"{\n"
|
||||||
" abc->a();\n"
|
" Foo<int> *abc = 0;\n"
|
||||||
"}\n");
|
" abc->a();\n"
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Possible null pointer dereference: abc\n", errout.str());
|
"}\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"
|
check("static void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -899,6 +915,13 @@ private:
|
||||||
" int x = &fred->x;\n"
|
" int x = &fred->x;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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
|
// Ticket #2350
|
||||||
|
|
Loading…
Reference in New Issue