speed up checks by caching commonly looked up stuff in the symbol database (CheckOther). Ticket: #4266
This commit is contained in:
parent
04d04c33c2
commit
09eed80938
|
@ -1532,8 +1532,10 @@ void CheckOther::checkComparisonOfBoolWithInt()
|
|||
return;
|
||||
|
||||
const SymbolDatabase* const 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 (tok->next() && tok->next()->type() == Token::eComparisonOp && (!tok->previous() || !tok->previous()->isArithmeticalOp()) && (!tok->tokAt(3) || !tok->tokAt(3)->isArithmeticalOp())) {
|
||||
const Token* const right = tok->tokAt(2);
|
||||
if ((tok->varId() && right->isNumber()) || (tok->isNumber() && right->varId())) { // Comparing variable with number
|
||||
|
@ -1572,6 +1574,7 @@ void CheckOther::checkComparisonOfBoolWithInt()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::comparisonOfBoolWithIntError(const Token *tok, const std::string &expression, bool n0o1)
|
||||
|
@ -1700,12 +1703,16 @@ static bool isSigned(const Variable* var)
|
|||
|
||||
void CheckOther::checkUnsignedDivision()
|
||||
{
|
||||
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
bool style = _settings->isEnabled("style");
|
||||
|
||||
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];
|
||||
const Token* ifTok = 0;
|
||||
// Check for "ivar / uvar" and "uvar / ivar"
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
|
||||
if (Token::Match(tok, "[).]")) // Don't check members or casted variables
|
||||
continue;
|
||||
|
||||
|
@ -1728,6 +1735,7 @@ void CheckOther::checkUnsignedDivision()
|
|||
else if (ifTok == tok)
|
||||
ifTok = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::udivError(const Token *tok, bool inconclusive)
|
||||
|
@ -1746,13 +1754,18 @@ void CheckOther::checkMemsetZeroBytes()
|
|||
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->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::simpleMatch(tok, "memset (")) {
|
||||
const Token* lastParamTok = tok->next()->link()->previous();
|
||||
if (lastParamTok->str() == "0")
|
||||
memsetZeroBytesError(tok, tok->strAt(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname)
|
||||
|
@ -1974,8 +1987,10 @@ void CheckOther::checkCharVariable()
|
|||
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->str() != ".") && Token::Match(tok->next(), "%var% [ %var% ]")) {
|
||||
const Variable* arrayvar = symbolDatabase->getVariableFromVarId(tok->next()->varId());
|
||||
const Variable* indexvar = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId());
|
||||
|
@ -2018,6 +2033,7 @@ void CheckOther::checkCharVariable()
|
|||
charBitOpError(tok->tokAt(4)); // This is an error..
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::charArrayIndexError(const Token *tok)
|
||||
|
@ -2099,8 +2115,10 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type)
|
|||
void CheckOther::strPlusChar()
|
||||
{
|
||||
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, "[=(] %str% + %any%")) {
|
||||
// char constant..
|
||||
if (tok->tokAt(3)->type() == Token::eChar)
|
||||
|
@ -2112,6 +2130,7 @@ void CheckOther::strPlusChar()
|
|||
strPlusCharError(tok->next());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::strPlusCharError(const Token *tok)
|
||||
|
@ -2145,14 +2164,11 @@ void CheckOther::zerodivError(const Token *tok)
|
|||
//---------------------------------------------------------------------------
|
||||
void CheckOther::checkMathFunctions()
|
||||
{
|
||||
const SymbolDatabase *db = _tokenizer->getSymbolDatabase();
|
||||
|
||||
std::list<Scope>::const_iterator scope;
|
||||
for (scope = db->scopeList.begin(); scope != db->scopeList.end(); ++scope) {
|
||||
if (scope->type != Scope::eFunction)
|
||||
continue;
|
||||
|
||||
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; 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 != scope->classEnd; tok = tok->next()) {
|
||||
if (tok->varId())
|
||||
continue;
|
||||
if (Token::Match(tok, "log|log10 ( %num% )")) {
|
||||
|
@ -2240,12 +2256,9 @@ void CheckOther::checkMisusedScopedObject()
|
|||
}
|
||||
|
||||
const SymbolDatabase * const 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];
|
||||
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "[;{}] %var% (")
|
||||
&& Token::simpleMatch(tok->linkAt(2), ") ;")
|
||||
|
@ -2403,7 +2416,11 @@ void CheckOther::checkIncorrectStringCompare()
|
|||
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->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, ". substr ( %any% , %num% ) ==|!= %str%")) {
|
||||
MathLib::bigint clen = MathLib::toLongNumber(tok->strAt(5));
|
||||
std::size_t slen = Token::getStrLength(tok->tokAt(8));
|
||||
|
@ -2428,6 +2445,7 @@ void CheckOther::checkIncorrectStringCompare()
|
|||
incorrectStringBooleanError(tok->tokAt(2), tok->strAt(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string)
|
||||
|
@ -3195,12 +3213,18 @@ void CheckOther::suspiciousStringCompareError(const Token* tok, const std::strin
|
|||
//-----------------------------------------------------------------------------
|
||||
void CheckOther::checkModuloAlwaysTrueFalse()
|
||||
{
|
||||
for (const Token* tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "% %num% ==|!=|<=|<|>|>= %num%") && (!tok->tokAt(4) || !tok->tokAt(4)->isArithmeticalOp())) {
|
||||
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 != scope->classEnd; tok = tok->next()) {
|
||||
if ((Token::Match(tok, "% %num% %op% %num%") && tok->tokAt(2)->isComparisonOp()) &&
|
||||
(!tok->tokAt(4) || !tok->tokAt(4)->isArithmeticalOp())) {
|
||||
if (MathLib::isLessEqual(tok->strAt(1), tok->strAt(3)))
|
||||
moduloAlwaysTrueFalseError(tok, tok->strAt(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal)
|
||||
|
@ -3302,10 +3326,12 @@ void CheckOther::divideSizeofError(const Token *tok)
|
|||
//-----------------------------------------------------------------------------
|
||||
void CheckOther::checkAssignBoolToPointer()
|
||||
{
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "!!* %var% = %bool% ;")) {
|
||||
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 != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "!!* %var% = %bool% ;")) {
|
||||
const Variable *var1(symbolDatabase->getVariableFromVarId(tok->next()->varId()));
|
||||
|
||||
// Is variable a pointer?
|
||||
|
@ -3313,6 +3339,7 @@ void CheckOther::checkAssignBoolToPointer()
|
|||
assignBoolToPointerError(tok->next());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::assignBoolToPointerError(const Token *tok)
|
||||
|
@ -3330,7 +3357,10 @@ void CheckOther::checkComparisonOfBoolExpressionWithInt()
|
|||
|
||||
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()) {
|
||||
// Skip template parameters
|
||||
if (tok->str() == "<" && tok->link()) {
|
||||
tok = tok->link();
|
||||
|
@ -3340,24 +3370,24 @@ void CheckOther::checkComparisonOfBoolExpressionWithInt()
|
|||
const Token* numTok = 0;
|
||||
const Token* opTok = 0;
|
||||
char op = 0;
|
||||
if (Token::Match(tok, "&&|%oror% %any% ) >|>=|==|!=|<=|< %any%")) {
|
||||
if (Token::Match(tok, "&&|%oror% %any% ) %op% %any%") && tok->tokAt(3)->isComparisonOp()) {
|
||||
numTok = tok->tokAt(4);
|
||||
opTok = tok->tokAt(3);
|
||||
if (Token::Match(opTok, "<|>"))
|
||||
op = opTok->str()[0];
|
||||
} else if (Token::Match(tok, "%any% >|>=|==|!=|<=|< ( %any% &&|%oror%")) {
|
||||
} else if (Token::Match(tok, "%any% %op% ( %any% &&|%oror%") && tok->next()->isComparisonOp()) {
|
||||
numTok = tok;
|
||||
opTok = tok->next();
|
||||
if (Token::Match(opTok, "<|>"))
|
||||
op = opTok->str()[0]=='>'?'<':'>';
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "! %var% >|>=|==|!=|<=|< %any%")) {
|
||||
else if (Token::Match(tok, "! %var% %op% %any%") && tok->tokAt(2)->isComparisonOp()) {
|
||||
numTok = tok->tokAt(3);
|
||||
opTok = tok->tokAt(2);
|
||||
if (Token::Match(opTok, "<|>"))
|
||||
op = opTok->str()[0];
|
||||
} else if (Token::Match(tok, "%any% >|>=|==|!=|<=|< ! %var%")) {
|
||||
} else if (Token::Match(tok, "%any% %op% ! %var%") && tok->next()->isComparisonOp()) {
|
||||
numTok = tok;
|
||||
opTok = tok->next();
|
||||
if (Token::Match(opTok, "<|>"))
|
||||
|
@ -3372,6 +3402,7 @@ void CheckOther::checkComparisonOfBoolExpressionWithInt()
|
|||
comparisonOfBoolExpressionWithIntError(tok, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::comparisonOfBoolExpressionWithIntError(const Token *tok, bool n0o1)
|
||||
|
@ -3399,15 +3430,11 @@ void CheckOther::checkSignOfUnsignedVariable()
|
|||
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
std::list<Scope>::const_iterator scope;
|
||||
|
||||
for (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];
|
||||
// check all the code in the function
|
||||
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
|
||||
for (const Token *tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "%var% <|<= 0") && tok->varId() && !Token::Match(tok->previous(), "++|--|)|+|-|*|/|~|<<|>>") && !Token::Match(tok->tokAt(3), "+|-")) {
|
||||
const Variable * var = symbolDatabase->getVariableFromVarId(tok->varId());
|
||||
if (var && var->typeEndToken()->isUnsigned())
|
||||
|
|
Loading…
Reference in New Issue