speed up checks by caching commonly looked up stuff in the symbol database (checkother, checkstl, checkunusedvar). Ticket: #4266

This commit is contained in:
Robert Reif 2012-11-16 06:50:49 +01:00 committed by Daniel Marjamäki
parent a2febc49d6
commit 6b8e83a181
3 changed files with 316 additions and 278 deletions

View File

@ -3180,8 +3180,10 @@ void CheckOther::checkSuspiciousStringCompare()
return;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token* tok = _tokenizer->list.front(); tok && tok->tokAt(3); tok = tok->next()) {
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (tok->next()->type() != Token::eComparisonOp)
continue;
@ -3203,6 +3205,7 @@ void CheckOther::checkSuspiciousStringCompare()
}
}
}
}
}
void CheckOther::suspiciousStringCompareError(const Token* tok, const std::string& var)
@ -3568,7 +3571,11 @@ void CheckOther::checkNegativeBitwiseShift()
{
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token *tok = _tokenizer->tokens(); tok ; tok = tok->next()) {
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if ((Token::Match(tok,"%var% >>|<< %num%") || Token::Match(tok,"%num% >>|<< %num%")) && !Token::Match(tok->previous(),">>|<<")) {
if (tok->isName()) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->varId());
@ -3580,6 +3587,7 @@ void CheckOther::checkNegativeBitwiseShift()
}
}
}
}
}
@ -3599,7 +3607,10 @@ void CheckOther::checkIncompleteArrayFill()
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token* tok = _tokenizer->list.front(); tok; tok = tok->next()) {
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "memset|memcpy|memmove ( %var% ,") && Token::Match(tok->linkAt(1)->tokAt(-2), ", %num% )")) {
const Variable* var = symbolDatabase->getVariableFromVarId(tok->tokAt(2)->varId());
if (!var || !var->isArray() || var->dimensions().empty() || !var->dimension(0))
@ -3614,6 +3625,7 @@ void CheckOther::checkIncompleteArrayFill()
}
}
}
}
}
void CheckOther::incompleteArrayFillError(const Token* tok, const std::string& buffer, const std::string& function, bool boolean)

View File

@ -238,7 +238,11 @@ void CheckStl::mismatchingContainers()
static const std::string pattern2 = pattern1x1_1 + pattern1x1_2;
// Check if different containers are used in various calls of standard functions
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t ii = 0; ii < functions; ++ii) {
const Scope * scope = symbolDatabase->functionScopes[ii];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (!Token::Match(tok, "std :: %type% ( !!)"))
continue;
const Token* arg1 = tok->tokAt(4);
@ -268,6 +272,7 @@ void CheckStl::mismatchingContainers()
}
tok = arg1->linkAt(-1);
}
}
}
@ -275,7 +280,7 @@ void CheckStl::stlOutOfBounds()
{
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
// Scan through all tokens..
// Scan through all scopes..
for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) {
const Token* const tok = i->classDef;
// only interested in "for" loops
@ -511,7 +516,11 @@ void CheckStl::erase()
void CheckStl::pushback()
{
// Pointer can become invalid after push_back, push_front, reserve or resize..
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% = & %var% [")) {
// Variable id for pointer
const unsigned int pointerId(tok->varId());
@ -553,9 +562,12 @@ void CheckStl::pushback()
}
}
}
}
// Iterator becomes invalid after reserve, resize, insert, push_back or push_front..
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (!Token::simpleMatch(tok, "vector <"))
continue;
@ -673,6 +685,7 @@ void CheckStl::pushback()
}
}
}
}
}
@ -697,7 +710,11 @@ void CheckStl::stlBoundries()
// containers (not the vector)..
static const char STL_CONTAINER_LIST[] = "bitset|deque|list|forward_list|map|multimap|multiset|priority_queue|queue|set|stack|hash_map|hash_multimap|hash_set|unordered_map|unordered_multimap|unordered_set|unordered_multiset";
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
// Declaring iterator..
if (tok->str() == "<" && Token::Match(tok->previous(), STL_CONTAINER_LIST)) {
const std::string& container_name(tok->strAt(-1));
@ -726,6 +743,7 @@ void CheckStl::stlBoundries()
}
}
}
}
}
// Error message for bad boundary usage..
@ -916,7 +934,11 @@ void CheckStl::size()
if (!_settings->isEnabled("performance"))
return;
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% . size ( )") ||
Token::Match(tok, "%var% . %var% . size ( )")) {
const Token *tok1 = tok;
@ -971,6 +993,7 @@ void CheckStl::size()
}
}
}
}
}
void CheckStl::sizeError(const Token *tok)
@ -1358,8 +1381,10 @@ void CheckStl::uselessCalls()
return;
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
if (tok->varId() && Token::Match(tok, "%var% . compare|find|rfind|find_first_not_of|find_first_of|find_last_not_of|find_last_of ( %var% [,)]") &&
tok->varId() == tok->tokAt(4)->varId() && style) {
uselessCallsReturnValueError(tok->tokAt(4), tok->str(), tok->strAt(2));
@ -1379,6 +1404,7 @@ void CheckStl::uselessCalls()
else if (Token::Match(tok, "[{};] std :: remove|remove_if|unique (") && tok->tokAt(5)->nextArgument())
uselessCallsRemoveError(tok->next(), tok->strAt(3));
}
}
}

View File

@ -968,10 +968,10 @@ void CheckUnusedVar::checkFunctionVariableUsage()
// Parse all executing scopes..
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
// only check functions
if (scope->type != Scope::eFunction)
continue;
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
// varId, usage {read, write, modified}
Variables variables;