speed up checks by caching commonly looked up stuff in the symbol database (CheckBufferOverrun, CheckBoost)

This commit is contained in:
Robert Reif 2012-10-13 11:16:48 +02:00 committed by Daniel Marjamäki
parent d7c7f8c9af
commit 0f8db28d30
2 changed files with 99 additions and 86 deletions

View File

@ -17,6 +17,7 @@
*/
#include "checkboost.h"
#include "symboldatabase.h"
// Register this check class (by creating a static instance of it)
namespace {
@ -25,7 +26,11 @@ namespace {
void CheckBoost::checkBoostForeachModification()
{
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 i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token *tok = scope->classStart->next(); tok && tok != scope->classEnd; tok = tok->next()) {
if (!Token::simpleMatch(tok, "BOOST_FOREACH ("))
continue;
@ -47,6 +52,7 @@ void CheckBoost::checkBoostForeachModification()
}
}
}
}
void CheckBoost::boostForeachError(const Token *tok)
{

View File

@ -1326,11 +1326,10 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
}
}
// find all dynamically allocated arrays next by parsing the token stream
// Count { and } when parsing all tokens
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
if (scope->type != Scope::eFunction)
continue;
// find all dynamically allocated arrays 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 the previous token exists, it must be either a variable name or "[;{}]"
@ -1423,13 +1422,10 @@ void CheckBufferOverrun::checkStructVariable()
{
const SymbolDatabase * symbolDatabase = _tokenizer->getSymbolDatabase();
std::list<Scope>::const_iterator scope;
// find every class and struct
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
// only check classes and structures
if (!scope->isClassOrStruct())
continue;
const std::size_t classes = symbolDatabase->classAndStructScopes.size();
for (std::size_t i = 0; i < classes; ++i) {
const Scope * scope = symbolDatabase->classAndStructScopes[i];
// check all variables to see if they are arrays
std::list<Variable>::const_iterator var;
@ -1439,13 +1435,10 @@ void CheckBufferOverrun::checkStructVariable()
// create ArrayInfo from the array variable
ArrayInfo arrayInfo(&*var, _tokenizer);
std::list<Scope>::const_iterator func_scope;
// find every function
for (func_scope = symbolDatabase->scopeList.begin(); func_scope != symbolDatabase->scopeList.end(); ++func_scope) {
// only check functions
if (func_scope->type != Scope::eFunction)
continue;
const std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t j = 0; j < functions; ++j) {
const Scope * func_scope = symbolDatabase->functionScopes[j];
// If struct is declared in a function then check
// if scope_func matches
@ -1570,8 +1563,8 @@ void CheckBufferOverrun::checkStructVariable()
ArrayInfo temp = arrayInfo;
temp.varid(0); // do variable lookup by variable and member names rather than varid
std::string varnames; // use class and member name for messages
for (unsigned int i = 0; i < varname.size(); ++i)
varnames += (i == 0 ? "" : ".") + varname[i];
for (unsigned int k = 0; k < varname.size(); ++k)
varnames += (k == 0 ? "" : ".") + varname[k];
temp.varname(varnames);
checkScope(CheckTok, varname, temp);
}
@ -1734,7 +1727,12 @@ void CheckBufferOverrun::checkSprintfCall(const Token *tok, const MathLib::bigin
//---------------------------------------------------------------------------
void CheckBufferOverrun::checkBufferAllocatedWithStrlen()
{
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 && tok != scope->classEnd; tok = tok->next()) {
unsigned int dstVarId;
unsigned int srcVarId;
@ -1774,6 +1772,7 @@ void CheckBufferOverrun::checkBufferAllocatedWithStrlen()
return;
}
}
}
//---------------------------------------------------------------------------
// Checking for buffer overflow caused by copying command line arguments
@ -1790,8 +1789,11 @@ void CheckBufferOverrun::checkInsecureCmdLineArgs()
{
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
for (std::list<Scope>::const_iterator i = symbolDatabase->scopeList.begin(); i != symbolDatabase->scopeList.end(); ++i) {
for (std::list<Function>::const_iterator j = i->functionList.begin(); j != i->functionList.end(); ++j) {
std::size_t functions = symbolDatabase->functionScopes.size();
for (std::size_t i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
Function * j = scope->function;
if (j) {
const Token* tok = j->token;
// Get the name of the argv variable
@ -1829,7 +1831,6 @@ void CheckBufferOverrun::checkInsecureCmdLineArgs()
tok->strAt(4).find("%s") != std::string::npos) {
cmdLineArgsError(tok);
}
}
}
}
@ -2087,7 +2088,12 @@ void CheckBufferOverrun::arrayIndexThenCheck()
{
if (!_settings->isEnabled("style"))
return;
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 i = 0; i < functions; ++i) {
const Scope * scope = symbolDatabase->functionScopes[i];
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
if (Token::Match(tok, "%var% [ %var% ]")) {
const std::string& indexName(tok->strAt(2));
@ -2110,6 +2116,7 @@ void CheckBufferOverrun::arrayIndexThenCheck()
}
}
}
}
void CheckBufferOverrun::arrayIndexThenCheckError(const Token *tok, const std::string &indexName)
{