Null pointers: Added comments

This commit is contained in:
Daniel Marjamäki 2011-01-06 13:18:49 +01:00
parent 04a117938d
commit 77ed6ecb5d
1 changed files with 35 additions and 1 deletions

View File

@ -430,20 +430,28 @@ void CheckNullPointer::nullPointerStructByDeRefAndChec()
void CheckNullPointer::nullPointerByDeRefAndChec() void CheckNullPointer::nullPointerByDeRefAndChec()
{ {
// Dereferencing a pointer and then checking if it's NULL.. // Dereferencing a pointer and then checking if it's NULL..
// This check will first scan for the check. And then scan backwards
// from the check, searching for dereferencing.
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{ {
// 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% )"))
{ {
// Variable id for pointer
const unsigned int varid(tok->tokAt(3)->varId()); const unsigned int varid(tok->tokAt(3)->varId());
if (varid == 0) if (varid == 0)
continue; continue;
// Name of pointer
const std::string varname(tok->strAt(3)); const std::string varname(tok->strAt(3));
// Check that variable is a pointer.. // Check that variable is a pointer..
if (!isPointer(varid)) if (!isPointer(varid))
continue; continue;
// Token where pointer is declared
const Token * const decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", varid); const Token * const decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", varid);
for (const Token *tok1 = tok->previous(); tok1 && tok1 != decltok; tok1 = tok1->previous()) for (const Token *tok1 = tok->previous(); tok1 && tok1 != decltok; tok1 = tok1->previous())
@ -455,7 +463,10 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
if (tok1->varId() == varid) if (tok1->varId() == varid)
{ {
// unknown : this is set by isPointerDeRef if it is
// uncertain
bool unknown = false; bool unknown = false;
if (Token::Match(tok1->tokAt(-2), "%varid% = %varid% .", varid)) if (Token::Match(tok1->tokAt(-2), "%varid% = %varid% .", varid))
{ {
break; break;
@ -490,7 +501,11 @@ void CheckNullPointer::nullPointerByDeRefAndChec()
void CheckNullPointer::nullPointerByCheckAndDeRef() void CheckNullPointer::nullPointerByCheckAndDeRef()
{ {
// Check if pointer is NULL and then dereference it.. // Check if pointer is NULL and then dereference it..
// used to check if a variable is a pointer.
// TODO: Use isPointer?
std::set<unsigned int> pointerVariables; std::set<unsigned int> pointerVariables;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{ {
if (Token::Match(tok, "* %var% [;,)=]")) if (Token::Match(tok, "* %var% [;,)=]"))
@ -498,6 +513,12 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
else if (Token::Match(tok, "if (")) else if (Token::Match(tok, "if ("))
{ {
// TODO: investigate false negatives:
// - handle "while"?
// - if there are logical operators
// - if (x) { } else { ... }
// vartok : token for the variable
const Token *vartok = 0; const Token *vartok = 0;
if (Token::Match(tok, "if ( ! %var% ) {")) if (Token::Match(tok, "if ( ! %var% ) {"))
vartok = tok->tokAt(3); vartok = tok->tokAt(3);
@ -508,16 +529,22 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
else else
continue; continue;
bool null = true; // variable id for pointer
const unsigned int varid(vartok->varId()); const unsigned int varid(vartok->varId());
if (varid == 0) if (varid == 0)
continue; continue;
// Check if variable is a pointer. TODO: Use isPointer?
if (pointerVariables.find(varid) == pointerVariables.end()) if (pointerVariables.find(varid) == pointerVariables.end())
continue; continue;
// if this is true then it is known that the pointer is null
bool null = true;
// Name of the pointer // Name of the pointer
const std::string &pointerName = vartok->str(); const std::string &pointerName = vartok->str();
// Count { and } for tok2
unsigned int indentlevel = 1; unsigned int indentlevel = 1;
for (const Token *tok2 = tok->next()->link()->tokAt(2); tok2; tok2 = tok2->next()) for (const Token *tok2 = tok->next()->link()->tokAt(2); tok2; tok2 = tok2->next())
{ {
@ -561,6 +588,9 @@ void CheckNullPointer::nullPointerByCheckAndDeRef()
if (tok2->varId() == varid) if (tok2->varId() == varid)
{ {
// unknown: this is set to true by isPointerDeRef if
// the function fails to determine if there
// is a dereference or not
bool unknown = false; bool unknown = false;
if (Token::Match(tok2->previous(), "[;{}=] %var% = 0 ;")) if (Token::Match(tok2->previous(), "[;{}=] %var% = 0 ;"))
@ -817,7 +847,11 @@ private:
if (tok.varId() != 0) if (tok.varId() != 0)
{ {
// unknown : not really used. it is passed to isPointerDeRef.
// if isPointerDeRef fails to determine if there
// is a dereference the this will be set to true.
bool unknown = false; bool unknown = false;
if (Token::Match(tok.previous(), "[;{}=] %var% = 0 ;")) if (Token::Match(tok.previous(), "[;{}=] %var% = 0 ;"))
setnull(checks, tok.varId()); setnull(checks, tok.varId());
else if (CheckNullPointer::isPointerDeRef(&tok, unknown)) else if (CheckNullPointer::isPointerDeRef(&tok, unknown))