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:
parent
0b39fedd45
commit
feefa4c626
|
@ -1256,29 +1256,35 @@ 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);
|
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;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
else if (Token::Match(tok, "%varid% [", declarationId)) {
|
else if (Token::Match(tok, "%var% (")) {
|
||||||
valueFlowCheckArrayIndex(tok->next(), arrayInfo);
|
// Loop..
|
||||||
}
|
if (Token::simpleMatch(tok, "for (")) {
|
||||||
|
bool bailout = false;
|
||||||
|
arrayIndexInForLoop(tok, arrayInfo);
|
||||||
|
checkScopeForBody(tok, arrayInfo, bailout);
|
||||||
|
if (bailout)
|
||||||
|
break;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Loop..
|
// Check function call..
|
||||||
else if (Token::simpleMatch(tok, "for (")) {
|
|
||||||
bool bailout = false;
|
|
||||||
arrayIndexInForLoop(tok, arrayInfo);
|
|
||||||
checkScopeForBody(tok, arrayInfo, bailout);
|
|
||||||
if (bailout)
|
|
||||||
break;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// 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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue