speed up checks by caching commonly looked up stuff in the symbol database (checkother, checkstl, checkunusedvar). Ticket: #4266
This commit is contained in:
parent
a2febc49d6
commit
6b8e83a181
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue