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;
|
return;
|
||||||
|
|
||||||
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
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 (tok->next() && tok->next()->type() == Token::eComparisonOp && (!tok->previous() || !tok->previous()->isArithmeticalOp()) && (!tok->tokAt(3) || !tok->tokAt(3)->isArithmeticalOp())) {
|
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);
|
const Token* const right = tok->tokAt(2);
|
||||||
if ((tok->varId() && right->isNumber()) || (tok->isNumber() && right->varId())) { // Comparing variable with number
|
if ((tok->varId() && right->isNumber()) || (tok->isNumber() && right->varId())) { // Comparing variable with number
|
||||||
|
@ -1573,6 +1575,7 @@ void CheckOther::checkComparisonOfBoolWithInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::comparisonOfBoolWithIntError(const Token *tok, const std::string &expression, bool n0o1)
|
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()
|
void CheckOther::checkUnsignedDivision()
|
||||||
{
|
{
|
||||||
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
|
||||||
bool style = _settings->isEnabled("style");
|
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;
|
const Token* ifTok = 0;
|
||||||
// Check for "ivar / uvar" and "uvar / ivar"
|
// 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
|
if (Token::Match(tok, "[).]")) // Don't check members or casted variables
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -1729,6 +1736,7 @@ void CheckOther::checkUnsignedDivision()
|
||||||
ifTok = 0;
|
ifTok = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::udivError(const Token *tok, bool inconclusive)
|
void CheckOther::udivError(const Token *tok, bool inconclusive)
|
||||||
{
|
{
|
||||||
|
@ -1746,7 +1754,11 @@ void CheckOther::checkMemsetZeroBytes()
|
||||||
if (!_settings->isEnabled("style"))
|
if (!_settings->isEnabled("style"))
|
||||||
return;
|
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 (")) {
|
if (Token::simpleMatch(tok, "memset (")) {
|
||||||
const Token* lastParamTok = tok->next()->link()->previous();
|
const Token* lastParamTok = tok->next()->link()->previous();
|
||||||
if (lastParamTok->str() == "0")
|
if (lastParamTok->str() == "0")
|
||||||
|
@ -1754,6 +1766,7 @@ void CheckOther::checkMemsetZeroBytes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname)
|
void CheckOther::memsetZeroBytesError(const Token *tok, const std::string &varname)
|
||||||
{
|
{
|
||||||
|
@ -1974,8 +1987,10 @@ void CheckOther::checkCharVariable()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
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; tok != scope->classEnd; tok = tok->next()) {
|
||||||
if ((tok->str() != ".") && Token::Match(tok->next(), "%var% [ %var% ]")) {
|
if ((tok->str() != ".") && Token::Match(tok->next(), "%var% [ %var% ]")) {
|
||||||
const Variable* arrayvar = symbolDatabase->getVariableFromVarId(tok->next()->varId());
|
const Variable* arrayvar = symbolDatabase->getVariableFromVarId(tok->next()->varId());
|
||||||
const Variable* indexvar = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId());
|
const Variable* indexvar = symbolDatabase->getVariableFromVarId(tok->tokAt(3)->varId());
|
||||||
|
@ -2019,6 +2034,7 @@ void CheckOther::checkCharVariable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::charArrayIndexError(const Token *tok)
|
void CheckOther::charArrayIndexError(const Token *tok)
|
||||||
{
|
{
|
||||||
|
@ -2099,8 +2115,10 @@ void CheckOther::constStatementError(const Token *tok, const std::string &type)
|
||||||
void CheckOther::strPlusChar()
|
void CheckOther::strPlusChar()
|
||||||
{
|
{
|
||||||
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
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::Match(tok, "[=(] %str% + %any%")) {
|
if (Token::Match(tok, "[=(] %str% + %any%")) {
|
||||||
// char constant..
|
// char constant..
|
||||||
if (tok->tokAt(3)->type() == Token::eChar)
|
if (tok->tokAt(3)->type() == Token::eChar)
|
||||||
|
@ -2113,6 +2131,7 @@ void CheckOther::strPlusChar()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::strPlusCharError(const Token *tok)
|
void CheckOther::strPlusCharError(const Token *tok)
|
||||||
{
|
{
|
||||||
|
@ -2145,14 +2164,11 @@ void CheckOther::zerodivError(const Token *tok)
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void CheckOther::checkMathFunctions()
|
void CheckOther::checkMathFunctions()
|
||||||
{
|
{
|
||||||
const SymbolDatabase *db = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
std::list<Scope>::const_iterator scope;
|
for (std::size_t i = 0; i < functions; ++i) {
|
||||||
for (scope = db->scopeList.begin(); scope != db->scopeList.end(); ++scope) {
|
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||||
if (scope->type != Scope::eFunction)
|
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||||
continue;
|
|
||||||
|
|
||||||
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
|
|
||||||
if (tok->varId())
|
if (tok->varId())
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "log|log10 ( %num% )")) {
|
if (Token::Match(tok, "log|log10 ( %num% )")) {
|
||||||
|
@ -2240,12 +2256,9 @@ void CheckOther::checkMisusedScopedObject()
|
||||||
}
|
}
|
||||||
|
|
||||||
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase * const symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
for (std::list<Scope>::const_iterator scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
for (std::size_t i = 0; i < functions; ++i) {
|
||||||
// only check functions
|
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||||
if (scope->type != Scope::eFunction)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
|
for (const Token *tok = scope->classStart; tok && tok != scope->classEnd; tok = tok->next()) {
|
||||||
if (Token::Match(tok, "[;{}] %var% (")
|
if (Token::Match(tok, "[;{}] %var% (")
|
||||||
&& Token::simpleMatch(tok->linkAt(2), ") ;")
|
&& Token::simpleMatch(tok->linkAt(2), ") ;")
|
||||||
|
@ -2403,7 +2416,11 @@ void CheckOther::checkIncorrectStringCompare()
|
||||||
if (!_settings->isEnabled("style"))
|
if (!_settings->isEnabled("style"))
|
||||||
return;
|
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%")) {
|
if (Token::Match(tok, ". substr ( %any% , %num% ) ==|!= %str%")) {
|
||||||
MathLib::bigint clen = MathLib::toLongNumber(tok->strAt(5));
|
MathLib::bigint clen = MathLib::toLongNumber(tok->strAt(5));
|
||||||
std::size_t slen = Token::getStrLength(tok->tokAt(8));
|
std::size_t slen = Token::getStrLength(tok->tokAt(8));
|
||||||
|
@ -2429,6 +2446,7 @@ void CheckOther::checkIncorrectStringCompare()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string)
|
void CheckOther::incorrectStringCompareError(const Token *tok, const std::string& func, const std::string &string)
|
||||||
{
|
{
|
||||||
|
@ -3195,13 +3213,19 @@ void CheckOther::suspiciousStringCompareError(const Token* tok, const std::strin
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CheckOther::checkModuloAlwaysTrueFalse()
|
void CheckOther::checkModuloAlwaysTrueFalse()
|
||||||
{
|
{
|
||||||
for (const Token* tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
if (Token::Match(tok, "% %num% ==|!=|<=|<|>|>= %num%") && (!tok->tokAt(4) || !tok->tokAt(4)->isArithmeticalOp())) {
|
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)))
|
if (MathLib::isLessEqual(tok->strAt(1), tok->strAt(3)))
|
||||||
moduloAlwaysTrueFalseError(tok, tok->strAt(1));
|
moduloAlwaysTrueFalseError(tok, tok->strAt(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal)
|
void CheckOther::moduloAlwaysTrueFalseError(const Token* tok, const std::string& maxVal)
|
||||||
{
|
{
|
||||||
|
@ -3302,10 +3326,12 @@ void CheckOther::divideSizeofError(const Token *tok)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void CheckOther::checkAssignBoolToPointer()
|
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 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()));
|
const Variable *var1(symbolDatabase->getVariableFromVarId(tok->next()->varId()));
|
||||||
|
|
||||||
// Is variable a pointer?
|
// Is variable a pointer?
|
||||||
|
@ -3314,6 +3340,7 @@ void CheckOther::checkAssignBoolToPointer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::assignBoolToPointerError(const Token *tok)
|
void CheckOther::assignBoolToPointerError(const Token *tok)
|
||||||
{
|
{
|
||||||
|
@ -3330,7 +3357,10 @@ void CheckOther::checkComparisonOfBoolExpressionWithInt()
|
||||||
|
|
||||||
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
|
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
|
// Skip template parameters
|
||||||
if (tok->str() == "<" && tok->link()) {
|
if (tok->str() == "<" && tok->link()) {
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
@ -3340,24 +3370,24 @@ void CheckOther::checkComparisonOfBoolExpressionWithInt()
|
||||||
const Token* numTok = 0;
|
const Token* numTok = 0;
|
||||||
const Token* opTok = 0;
|
const Token* opTok = 0;
|
||||||
char op = 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);
|
numTok = tok->tokAt(4);
|
||||||
opTok = tok->tokAt(3);
|
opTok = tok->tokAt(3);
|
||||||
if (Token::Match(opTok, "<|>"))
|
if (Token::Match(opTok, "<|>"))
|
||||||
op = opTok->str()[0];
|
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;
|
numTok = tok;
|
||||||
opTok = tok->next();
|
opTok = tok->next();
|
||||||
if (Token::Match(opTok, "<|>"))
|
if (Token::Match(opTok, "<|>"))
|
||||||
op = opTok->str()[0]=='>'?'<':'>';
|
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);
|
numTok = tok->tokAt(3);
|
||||||
opTok = tok->tokAt(2);
|
opTok = tok->tokAt(2);
|
||||||
if (Token::Match(opTok, "<|>"))
|
if (Token::Match(opTok, "<|>"))
|
||||||
op = opTok->str()[0];
|
op = opTok->str()[0];
|
||||||
} else if (Token::Match(tok, "%any% >|>=|==|!=|<=|< ! %var%")) {
|
} else if (Token::Match(tok, "%any% %op% ! %var%") && tok->next()->isComparisonOp()) {
|
||||||
numTok = tok;
|
numTok = tok;
|
||||||
opTok = tok->next();
|
opTok = tok->next();
|
||||||
if (Token::Match(opTok, "<|>"))
|
if (Token::Match(opTok, "<|>"))
|
||||||
|
@ -3373,6 +3403,7 @@ void CheckOther::checkComparisonOfBoolExpressionWithInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CheckOther::comparisonOfBoolExpressionWithIntError(const Token *tok, bool n0o1)
|
void CheckOther::comparisonOfBoolExpressionWithIntError(const Token *tok, bool n0o1)
|
||||||
{
|
{
|
||||||
|
@ -3399,15 +3430,11 @@ void CheckOther::checkSignOfUnsignedVariable()
|
||||||
|
|
||||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||||
|
|
||||||
std::list<Scope>::const_iterator scope;
|
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||||
|
for (std::size_t i = 0; i < functions; ++i) {
|
||||||
for (scope = symbolDatabase->scopeList.begin(); scope != symbolDatabase->scopeList.end(); ++scope) {
|
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||||
// only check functions
|
|
||||||
if (scope->type != Scope::eFunction)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// check all the code in the function
|
// 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), "+|-")) {
|
if (Token::Match(tok, "%var% <|<= 0") && tok->varId() && !Token::Match(tok->previous(), "++|--|)|+|-|*|/|~|<<|>>") && !Token::Match(tok->tokAt(3), "+|-")) {
|
||||||
const Variable * var = symbolDatabase->getVariableFromVarId(tok->varId());
|
const Variable * var = symbolDatabase->getVariableFromVarId(tok->varId());
|
||||||
if (var && var->typeEndToken()->isUnsigned())
|
if (var && var->typeEndToken()->isUnsigned())
|
||||||
|
|
Loading…
Reference in New Issue