Fixed #2954 (False negative: Null pointer dereference not detected '*p=4; if (p) { }')

This commit is contained in:
Daniel Marjamäki 2011-08-02 11:20:09 +02:00
parent 5fc2a55bac
commit 825dce5c4e
2 changed files with 22 additions and 15 deletions

View File

@ -513,15 +513,19 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
// TODO: false negatives.
// - logical operators
// - while
if (tok->str() == "if" && Token::Match(tok->previous(), "; if ( ! %var% )"))
if (tok->str() == "if" && Token::Match(tok->previous(), "; if ( !| %var% )"))
{
const Token * vartok = tok->tokAt(2);
if (vartok->str() == "!")
vartok = vartok->next();
// Variable id for pointer
const unsigned int varid(tok->tokAt(3)->varId());
const unsigned int varid(vartok->varId());
if (varid == 0)
continue;
// Name of pointer
const std::string varname(tok->strAt(3));
const std::string varname(vartok->str());
// Check that variable is a pointer..
if (!isPointer(varid))
@ -535,8 +539,10 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
if (tok1->str() == ")" && Token::Match(tok1->link()->previous(), "%var% ("))
{
const Token *tok2 = tok1->link();
while (tok2 && !Token::Match(tok2, "[;{}]"))
while (tok2 && !Token::Match(tok2, "[;{}?:]"))
tok2 = tok2->previous();
if (Token::Match(tok2, "[?:]"))
break;
if (Token::Match(tok2, "[;{}] %varid% = %var%", varid))
break;
@ -559,6 +565,11 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
break;
}
}
// calling unknown function => it might initialize the pointer
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(varid);
if (!var || !(var->isLocal() || var->isArgument()))
break;
}
if (tok1->str() == "break")

View File

@ -306,17 +306,6 @@ private:
ASSERT_EQUALS("", errout.str());
// loops..
check("void freeAbc(struct ABC *abc)\n"
"{\n"
" while (abc)\n"
" {\n"
" struct ABC *next = abc->next;\n"
" if (abc) delete abc;\n"
" abc = next;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
check("void foo(struct ABC *abc)\n"
"{\n"
" int a = abc->a;"
@ -410,6 +399,13 @@ private:
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 4\n", errout.str());
check("void foo(int *p)\n"
"{\n"
" *p = 0;\n"
" if (p) { }\n"
"}\n");
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 4\n", errout.str());
check("void foo(int *p)\n"
"{\n"
" bar(*p);\n"