Speedup checking large amounts of arrays (#5615) by avoiding Token::Match calls in CheckBufferOverrun::checkScope(2).

-> Decreased entire checking time on a subset of the attached file by 66% (MSVC12, x64, non-matchcompiled)
This commit is contained in:
PKEuS 2014-06-26 10:35:54 +02:00
parent 0b39fedd45
commit feefa4c626
1 changed files with 26 additions and 27 deletions

View File

@ -1256,18 +1256,26 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
const bool isWarningEnabled = _settings->isEnabled("warning"); const bool isWarningEnabled = _settings->isEnabled("warning");
for (const Token* const end = tok->scope()->classEnd; tok != end; tok = tok->next()) { for (const Token* const end = tok->scope()->classEnd; tok != end; tok = tok->next()) {
// Skip array declarations if (tok->varId() == declarationId) {
if (Token::Match(tok, "[;{}] %type% *| %var% [") && tok->strAt(1) != "return") { if (tok->strAt(1) == "[") {
tok = tok->tokAt(3);
continue;
}
else if (Token::Match(tok, "%varid% [", declarationId)) {
valueFlowCheckArrayIndex(tok->next(), arrayInfo); valueFlowCheckArrayIndex(tok->next(), arrayInfo);
} }
// undefined behaviour: result of pointer arithmetic is out of bounds
else if (isPortabilityEnabled && Token::Match(tok->previous(), "= %varid% + %num% ;", declarationId)) {
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(2));
if (index < 0 || index > arrayInfo.num(0)) {
pointerOutOfBoundsError(tok, "array");
}
}
}
else if (!tok->scope()->isExecutable()) // No executable code outside of executable scope - continue to increase performance
continue;
else if (Token::Match(tok, "%var% (")) {
// Loop.. // Loop..
else if (Token::simpleMatch(tok, "for (")) { if (Token::simpleMatch(tok, "for (")) {
bool bailout = false; bool bailout = false;
arrayIndexInForLoop(tok, arrayInfo); arrayIndexInForLoop(tok, arrayInfo);
checkScopeForBody(tok, arrayInfo, bailout); checkScopeForBody(tok, arrayInfo, bailout);
@ -1276,9 +1284,7 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
continue; continue;
} }
// Check function call.. // Check function call..
if (Token::Match(tok, "%var% (")) {
checkFunctionCall(tok, arrayInfo, std::list<const Token*>()); checkFunctionCall(tok, arrayInfo, std::list<const Token*>());
if (Token::Match(tok, "strncpy|memcpy|memmove ( %varid% , %str% , %num% )", declarationId)) { if (Token::Match(tok, "strncpy|memcpy|memmove ( %varid% , %str% , %num% )", declarationId)) {
@ -1368,13 +1374,6 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
checkReadlinkBufferUsage(tok, scope_begin, declarationId, total_size); checkReadlinkBufferUsage(tok, scope_begin, declarationId, total_size);
} }
// undefined behaviour: result of pointer arithmetic is out of bounds
if (isPortabilityEnabled && Token::Match(tok, "= %varid% + %num% ;", declarationId)) {
const MathLib::bigint index = MathLib::toLongNumber(tok->strAt(3));
if (index < 0 || index > arrayInfo.num(0)) {
pointerOutOfBoundsError(tok->next(), "array");
}
}
} }
} }