Example #1
0
void CheckStl::iterators()
{
    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
    {
        if (!Token::Match(tok, "%var% = %var% . begin ( ) ;|+"))
            continue;

        const unsigned int iteratorId(tok->varId());
        const unsigned int containerId(tok->tokAt(2)->varId());
        if (iteratorId == 0 || containerId == 0)
            continue;

        bool validIterator = true;
        for (const Token *tok2 = tok->tokAt(7); tok2; tok2 = tok2->next())
        {
            if (tok2->str() == "}")
                break;

            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);
            }
            else if (Token::Match(tok2, "%var% . insert|erase ( %varid%", iteratorId))
            {
                if (tok2->varId() != containerId && tok2->tokAt(5)->str() != ".")
                    iteratorsError(tok2, tok->strAt(2), tok2->str());
                else if (tok2->strAt(2) == std::string("erase"))
                    validIterator = false;

                tok2 = tok2->tokAt(4);
            }
            else if (Token::Match(tok2, "%varid% = %var% . erase (", iteratorId))
            {
                validIterator = true;
                tok2 = tok2->tokAt(5)->link();
                if (!tok2)
                    break;
            }
            else if (!validIterator && Token::Match(tok2, "* %varid%", iteratorId))
            {
                dereferenceErasedError(tok2, tok2->strAt(1));
                tok2 = tok2->next();
            }
            else if (!validIterator && Token::Match(tok2, "%varid% . %var%", iteratorId))
            {
                dereferenceErasedError(tok2, tok2->strAt(0));
                tok2 = tok2->tokAt(2);
            }
        }
    }
}
Example #2
0
void CheckStl::iterators()
{
    for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next())
    {
        if (!Token::Match(tok, "%var% = %var% . begin ( ) ;|+"))
            continue;

        const unsigned int iteratorId(tok->varId());
        const unsigned int containerId(tok->tokAt(2)->varId());
        if (iteratorId == 0 || containerId == 0)
            continue;

        bool validIterator = true;
        unsigned int indent = 0;
        for (const Token *tok2 = tok->tokAt(7); tok2; tok2 = tok2->next())
        {
            if (tok2->str() == "{" && ++indent)
                continue;
            if (tok2->str() == "}" && --indent == 0)
                break;

            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);
            }
            else if (Token::Match(tok2, "%var% . insert|erase ( %varid% )|,", iteratorId))
            {
                if (!validIterator)
                    invalidIteratorError(tok2, tok2->strAt(4));

                if (tok2->varId() != containerId && tok2->tokAt(5)->str() != ".")
                {
                    // skip error message if container is a set..
                    if (tok2->varId() > 0)
                    {
                        const Token *decltok = Token::findmatch(_tokenizer->tokens(), "%varid%", tok2->varId());
                        while (decltok && !Token::Match(decltok, "[;{},(]"))
                            decltok = decltok->previous();
                        if (Token::Match(decltok, "%any% const| std :: set"))
                            continue;	// No warning
                    }

                    // Show error message, mismatching iterator is used.
                    iteratorsError(tok2, tok->strAt(2), tok2->str());
                }
                else if (tok2->strAt(2) == std::string("erase"))
                    validIterator = false;

                tok2 = tok2->tokAt(4);
            }
            else if (Token::Match(tok2, "%varid% = %var% . erase (", iteratorId))
            {
                validIterator = true;
                tok2 = tok2->tokAt(5)->link();
                if (!tok2)
                    break;
            }
            else if (Token::Match(tok2, "%varid% = %var% ;", iteratorId))
            {
                validIterator = true;
                tok2 = tok2->tokAt(2);
            }
            else if (!validIterator && Token::Match(tok2, "* %varid%", iteratorId))
            {
                dereferenceErasedError(tok2, tok2->strAt(1));
                tok2 = tok2->next();
            }
            else if (!validIterator && Token::Match(tok2, "%varid% . %var%", iteratorId))
            {
                dereferenceErasedError(tok2, tok2->strAt(0));
                tok2 = tok2->tokAt(2);
            }
            else if (Token::Match(tok2, "%var% . erase ( * %varid%", iteratorId) && tok2->varId() == containerId)
            {
                eraseByValueError(tok2, tok2->strAt(0), tok2->strAt(5));
            }
            else if (Token::Match(tok2, "return|break ;"))
            {
                validIterator = true;
            }
        }
    }
}