CheckStl: Added comments

This commit is contained in:
Daniel Marjamäki 2010-12-30 22:36:25 +01:00
parent d005245188
commit c7f2ddf63c
1 changed files with 43 additions and 0 deletions

View File

@ -47,35 +47,54 @@ void CheckStl::dereferenceErasedError(const Token *tok, const std::string &itern
void CheckStl::iterators()
{
// Using same iterator against different containers.
// for (it = foo.begin(); it != bar.end(); ++it)
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
// Locate an iterator..
if (!Token::Match(tok, "%var% = %var% . begin ( ) ;|+"))
continue;
// Get variable ids for both the iterator and container
const unsigned int iteratorId(tok->varId());
const unsigned int containerId(tok->tokAt(2)->varId());
if (iteratorId == 0 || containerId == 0)
continue;
// the validIterator flag says if the iterator has a valid value or not
bool validIterator = true;
// counter for { and }
unsigned int indent = 0;
// Scan through the rest of the code and see if the iterator is
// used against other containers.
for (const Token *tok2 = tok->tokAt(7); tok2; tok2 = tok2->next())
{
// If a { is found then count it and continue
if (tok2->str() == "{" && ++indent)
continue;
// If a } is found then count it. break if indentlevel becomes 0.
if (tok2->str() == "}" && --indent == 0)
break;
// Is iterator compared against different container?
if (Token::Match(tok2, "%varid% != %var% . end ( )", iteratorId) && tok2->tokAt(2)->varId() != containerId)
{
iteratorsError(tok2, tok->strAt(2), tok2->strAt(2));
tok2 = tok2->tokAt(6);
}
// Is the iterator used in a insert/erase operation?
else if (Token::Match(tok2, "%var% . insert|erase ( %varid% )|,", iteratorId))
{
// It is bad to insert/erase an invalid iterator
if (!validIterator)
invalidIteratorError(tok2, tok2->strAt(4));
// If insert/erase is used on different container then
// report an error
if (tok2->varId() != containerId && tok2->tokAt(5)->str() != ".")
{
// skip error message if container is a set..
@ -91,23 +110,40 @@ void CheckStl::iterators()
// Show error message, mismatching iterator is used.
iteratorsError(tok2, tok->strAt(2), tok2->str());
}
// invalidate the iterator if it is erased
else if (tok2->strAt(2) == std::string("erase"))
validIterator = false;
// skip the operation
tok2 = tok2->tokAt(4);
}
// it = foo.erase(..
// taking the result of an erase is ok
else if (Token::Match(tok2, "%varid% = %var% . erase (", iteratorId))
{
// the returned iterator is valid
validIterator = true;
// skip the operation
tok2 = tok2->tokAt(5)->link();
if (!tok2)
break;
}
// Reassign the iterator
else if (Token::Match(tok2, "%varid% = %var% ;", iteratorId))
{
// Assume that the iterator becomes valid.
// TODO: is it valid?
validIterator = true;
// skip ahead
tok2 = tok2->tokAt(2);
}
// Dereferencing invalid iterator?
else if (!validIterator && Token::Match(tok2, "* %varid%", iteratorId))
{
dereferenceErasedError(tok2, tok2->strAt(1));
@ -122,10 +158,16 @@ void CheckStl::iterators()
{
// eraseByValueError(tok2, tok2->strAt(0), tok2->strAt(5));
}
// bailout handling. Assume that the iterator becomes valid if we see return/break.
// TODO: better handling
else if (Token::Match(tok2, "return|break ;"))
{
validIterator = true;
}
// bailout handling. Assume that the iterator becomes valid if we see else.
// TODO: better handling
else if (tok2->str() == "else")
{
validIterator = true;
@ -143,6 +185,7 @@ void CheckStl::mismatchingContainersError(const Token *tok)
void CheckStl::mismatchingContainers()
{
// Check if different containers are used in various calls of standard functions
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
{
if (tok->str() != "std")