null pointers: fixed todo test case

This commit is contained in:
Daniel Marjamäki 2010-08-05 08:06:19 +02:00
parent 9d24c9ceaa
commit 6f228033d2
2 changed files with 78 additions and 61 deletions

View File

@ -2336,84 +2336,98 @@ void CheckOther::nullPointerLinkedList()
void CheckOther::nullPointerStructByDeRefAndChec()
{
// Dereferencing a struct pointer and then checking if it's NULL..
for (const Token *tok1 = _tokenizer->tokens(); tok1; tok1 = tok1->next())
{
// dereference in assignment
if (Token::Match(tok1, "[{};] %var% = %var% . %var%"))
{
if (std::string(tok1->strAt(1)) == tok1->strAt(3))
continue;
tok1 = tok1->tokAt(3);
const unsigned int varid1(tok1->varId());
if (varid1 == 0)
continue;
}
const std::string varname(tok1->str());
// dereference in function call
else if (Token::Match(tok1->tokAt(-2), "%var% ( %var% . %var%") ||
Token::Match(tok1->previous(), ", %var% . %var%"))
{
// Checking if the struct pointer is non-null before the assignment..
}
// Goto next token
else
{
continue;
}
// struct dereference was found - investigate if it is later
// checked that it is not NULL
const unsigned int varid1(tok1->varId());
if (varid1 == 0)
continue;
const std::string varname(tok1->str());
// Checking if the struct pointer is non-null before the assignment..
{
const Token *tok2 = _tokenizer->tokens();
while (tok2)
{
const Token *tok2 = _tokenizer->tokens();
while (tok2)
{
if (tok2 == tok1)
break;
if (Token::Match(tok2, "if|while ( !| %varid% )", varid1))
break;
tok2 = tok2->next();
}
if (tok2 != tok1)
continue;
if (tok2 == tok1)
break;
if (Token::Match(tok2, "if|while ( !| %varid% )", varid1))
break;
tok2 = tok2->next();
}
if (tok2 != tok1)
continue;
}
unsigned int indentlevel2 = 0;
for (const Token *tok2 = tok1->tokAt(3); tok2; tok2 = tok2->next())
{
if (tok2->str() == "{")
++indentlevel2;
else if (tok2->str() == "}")
{
if (indentlevel2 == 0)
break;
--indentlevel2;
}
unsigned int indentlevel2 = 0;
for (const Token *tok2 = tok1->tokAt(3); tok2; tok2 = tok2->next())
// goto destination..
else if (tok2->isName() && Token::simpleMatch(tok2->next(), ":"))
break;
// Reassignment of the struct
else if (tok2->varId() == varid1)
{
if (tok2->str() == "{")
++indentlevel2;
else if (tok2->str() == "}")
{
if (indentlevel2 == 0)
break;
--indentlevel2;
}
// goto destination..
else if (tok2->isName() && Token::simpleMatch(tok2->next(), ":"))
if (tok2->next()->str() == "=")
break;
// Reassignment of the struct
else if (tok2->varId() == varid1)
{
if (tok2->next()->str() == "=")
break;
if (Token::Match(tok2->tokAt(-2), "[,(] &"))
break;
}
// Loop..
/** @todo don't bail out if the variable is not used in the loop */
else if (tok2->str() == "do")
if (Token::Match(tok2->tokAt(-2), "[,(] &"))
break;
}
// return at base level => stop checking
else if (indentlevel2 == 0 && tok2->str() == "return")
break;
// Loop..
/** @todo don't bail out if the variable is not used in the loop */
else if (tok2->str() == "do")
break;
else if (Token::Match(tok2, "if ( !| %varid% )", varid1))
{
// Is this variable a pointer?
const Token *tempTok = Token::findmatch(_tokenizer->tokens(), "%type% * %varid% [;)=]", varid1);
if (tempTok)
nullPointerError(tok1, varname, tok2->linenr());
break;
}
// return at base level => stop checking
else if (indentlevel2 == 0 && tok2->str() == "return")
break;
else if (Token::Match(tok2, "if ( !| %varid% )", varid1))
{
// Is this variable a pointer?
const Token *tempTok = Token::findmatch(_tokenizer->tokens(), "%type% * %varid% [;)=]", varid1);
if (tempTok)
nullPointerError(tok1, varname, tok2->linenr());
break;
}
}
}
}
void CheckOther::nullPointerByDeRefAndChec()
@ -2429,8 +2443,9 @@ void CheckOther::nullPointerByDeRefAndChec()
const std::string varname(tok->strAt(3));
// Check that variable is a pointer..
const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", varid);
if (!Token::Match(decltok->tokAt(-3), "[;,(] %var% *"))
if (!Token::Match(decltok->tokAt(-3), "[;,(] %type% *"))
continue;
for (const Token *tok1 = tok->previous(); tok1 && tok1 != decltok; tok1 = tok1->previous())
@ -2456,8 +2471,8 @@ void CheckOther::nullPointerByDeRefAndChec()
tok1->str() == "}")
break;
// goto destination..
else if (tok1->isName() && Token::simpleMatch(tok1->next(), ":"))
// label..
else if (Token::Match(tok1, "%type% :"))
break;
}
}

View File

@ -794,6 +794,8 @@ private:
}
// Dereferencing a struct and then checking if it is null
// This is checked by this function:
// CheckOther::nullPointerStructByDeRefAndChec
void nullpointer3()
{
// errors..
@ -811,7 +813,7 @@ private:
" if (!abc)\n"
" ;\n"
"}\n");
TODO_ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4\n", errout.str());
ASSERT_EQUALS("[test.cpp:3]: (error) Possible null pointer dereference: abc - otherwise it is redundant to check if abc is null at line 4\n", errout.str());
// ok dereferencing in a condition
checkNullPointer("void foo(struct ABC *abc)\n"