Fix 10768: performance regression (#3788)

This commit is contained in:
Paul Fultz II 2022-02-02 06:01:44 -06:00 committed by GitHub
parent 4af8734c29
commit 11387cbb41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 55 additions and 1 deletions

View File

@ -3388,6 +3388,60 @@ static void valueFlowLifetimeConstructor(Token *tok,
ErrorLogger *errorLogger,
const Settings *settings);
static const Token* getEndOfVarScope(const Variable* var)
{
if (!var)
return nullptr;
const Scope* innerScope = var->scope();
const Scope* outerScope = innerScope;
if (var->typeStartToken() && var->typeStartToken()->scope())
outerScope = var->typeStartToken()->scope();
if (!innerScope && outerScope)
innerScope = outerScope;
if (!innerScope || !outerScope)
return nullptr;
if (!innerScope->isExecutable())
return nullptr;
// If the variable is defined in a for/while initializer then we want to
// pick one token after the end so forward analysis can analyze the exit
// conditions
if (innerScope != outerScope && outerScope->isExecutable() && innerScope->isLocal())
return innerScope->bodyEnd->next();
return innerScope->bodyEnd;
}
static const Token* getEndOfExprScope(const Token* tok, const Scope* defaultScope = nullptr)
{
const Token* end = nullptr;
bool local = false;
visitAstNodes(tok, [&](const Token* child) {
if (const Variable* var = child->variable()) {
local |= var->isLocal();
if (var->isLocal() || var->isArgument()) {
const Token* varEnd = getEndOfVarScope(var);
if (!end || precedes(varEnd, end))
end = varEnd;
}
}
return ChildrenToVisit::op1_and_op2;
});
if (!end && defaultScope)
end = defaultScope->bodyEnd;
if (!end) {
const Scope* scope = tok->scope();
if (scope)
end = scope->bodyEnd;
// If there is no local variables then pick the function scope
if (!local) {
while (scope && scope->isLocal())
scope = scope->nestedIn;
if (scope && scope->isExecutable())
end = scope->bodyEnd;
}
}
return end;
}
static const Token* getEndOfVarScope(const Token* tok, const std::vector<const Variable*>& vars)
{
const Token* endOfVarScope = nullptr;
@ -5627,7 +5681,7 @@ struct ConditionHandler {
}
if (values.empty())
return;
forward(after, scope->bodyEnd, cond.vartok, values, tokenlist, settings);
forward(after, getEndOfExprScope(cond.vartok, scope), cond.vartok, values, tokenlist, settings);
}
});
}