various optimizations (#3054)
This commit is contained in:
parent
9f9a652ae1
commit
b2ed372f75
|
@ -551,11 +551,14 @@ bool extractForLoopValues(const Token *forToken,
|
||||||
|
|
||||||
static const Token * getVariableInitExpression(const Variable * var)
|
static const Token * getVariableInitExpression(const Variable * var)
|
||||||
{
|
{
|
||||||
if (!var || !var->declEndToken())
|
if (!var)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (Token::Match(var->declEndToken(), "; %varid% =", var->declarationId()))
|
const Token *varDeclEndToken = var->declEndToken();
|
||||||
return var->declEndToken()->tokAt(2)->astOperand2();
|
if (!varDeclEndToken)
|
||||||
return var->declEndToken()->astOperand2();
|
return nullptr;
|
||||||
|
if (Token::Match(varDeclEndToken, "; %varid% =", var->declarationId()))
|
||||||
|
return varDeclEndToken->tokAt(2)->astOperand2();
|
||||||
|
return varDeclEndToken->astOperand2();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isInLoopCondition(const Token * tok)
|
static bool isInLoopCondition(const Token * tok)
|
||||||
|
@ -729,13 +732,6 @@ static void followVariableExpressionError(const Token *tok1, const Token *tok2,
|
||||||
errors->push_back(item);
|
errors->push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void findTokenValue(const Token* const tok, std::function<bool(const ValueFlow::Value &)> pred, std::function<void(const ValueFlow::Value &)> f)
|
|
||||||
{
|
|
||||||
auto x = std::find_if(tok->values().begin(), tok->values().end(), pred);
|
|
||||||
if (x != tok->values().end())
|
|
||||||
f(*x);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isSameLifetime(const Token * const tok1, const Token * const tok2)
|
static bool isSameLifetime(const Token * const tok1, const Token * const tok2)
|
||||||
{
|
{
|
||||||
ValueFlow::Value v1 = getLifetimeObjValue(tok1);
|
ValueFlow::Value v1 = getLifetimeObjValue(tok1);
|
||||||
|
@ -747,18 +743,23 @@ static bool isSameLifetime(const Token * const tok1, const Token * const tok2)
|
||||||
|
|
||||||
static bool compareKnownValue(const Token * const tok1, const Token * const tok2, std::function<bool(const ValueFlow::Value&, const ValueFlow::Value&, bool)> compare)
|
static bool compareKnownValue(const Token * const tok1, const Token * const tok2, std::function<bool(const ValueFlow::Value&, const ValueFlow::Value&, bool)> compare)
|
||||||
{
|
{
|
||||||
bool result = false;
|
static const auto isKnownFn = std::mem_fn(&ValueFlow::Value::isKnown);
|
||||||
bool sameLifetime = isSameLifetime(tok1, tok2);
|
|
||||||
findTokenValue(tok1, std::mem_fn(&ValueFlow::Value::isKnown), [&](const ValueFlow::Value& v1) {
|
const auto v1 = std::find_if(tok1->values().begin(), tok1->values().end(), isKnownFn);
|
||||||
if (v1.isNonValue() || v1.isContainerSizeValue())
|
if (v1 == tok1->values().end()) {
|
||||||
return;
|
return false;
|
||||||
findTokenValue(tok2, std::mem_fn(&ValueFlow::Value::isKnown), [&](const ValueFlow::Value& v2) {
|
}
|
||||||
if (v1.valueType == v2.valueType) {
|
if (v1->isNonValue() || v1->isContainerSizeValue())
|
||||||
result = compare(v1, v2, sameLifetime);
|
return false;
|
||||||
}
|
const auto v2 = std::find_if(tok2->values().begin(), tok2->values().end(), isKnownFn);
|
||||||
});
|
if (v2 == tok2->values().end()) {
|
||||||
});
|
return false;
|
||||||
return result;
|
}
|
||||||
|
if (v1->valueType != v2->valueType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const bool sameLifetime = isSameLifetime(tok1, tok2);
|
||||||
|
return compare(*v1, *v2, sameLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isEqualKnownValue(const Token * const tok1, const Token * const tok2)
|
bool isEqualKnownValue(const Token * const tok1, const Token * const tok2)
|
||||||
|
|
|
@ -193,13 +193,13 @@ static void fillProgramMemoryFromConditions(ProgramMemory& pm, const Token* tok,
|
||||||
fillProgramMemoryFromConditions(pm, tok->scope(), tok, settings);
|
fillProgramMemoryFromConditions(pm, tok->scope(), tok, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok, const ProgramMemory& state, ProgramMemory::Map vars)
|
static void fillProgramMemoryFromAssignments(ProgramMemory& pm, const Token* tok, const ProgramMemory& state, const ProgramMemory::Map& vars)
|
||||||
{
|
{
|
||||||
int indentlevel = 0;
|
int indentlevel = 0;
|
||||||
for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) {
|
for (const Token *tok2 = tok; tok2; tok2 = tok2->previous()) {
|
||||||
bool setvar = false;
|
bool setvar = false;
|
||||||
if (Token::Match(tok2, "[;{}] %var% = %var% ;")) {
|
if (Token::Match(tok2, "[;{}] %var% = %var% ;")) {
|
||||||
for (auto&& p:vars) {
|
for (const auto& p:vars) {
|
||||||
if (p.first != tok2->next()->varId())
|
if (p.first != tok2->next()->varId())
|
||||||
continue;
|
continue;
|
||||||
const Token *vartok = tok2->tokAt(3);
|
const Token *vartok = tok2->tokAt(3);
|
||||||
|
@ -293,7 +293,6 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va
|
||||||
{
|
{
|
||||||
ProgramMemory pm;
|
ProgramMemory pm;
|
||||||
fillProgramMemoryFromConditions(pm, tok, nullptr);
|
fillProgramMemoryFromConditions(pm, tok, nullptr);
|
||||||
ProgramMemory local;
|
|
||||||
for (const auto& p:vars) {
|
for (const auto& p:vars) {
|
||||||
nonneg int varid = p.first;
|
nonneg int varid = p.first;
|
||||||
const ValueFlow::Value &value = p.second;
|
const ValueFlow::Value &value = p.second;
|
||||||
|
@ -301,7 +300,7 @@ void ProgramMemoryState::addState(const Token* tok, const ProgramMemory::Map& va
|
||||||
if (value.varId)
|
if (value.varId)
|
||||||
pm.setIntValue(value.varId, value.varvalue);
|
pm.setIntValue(value.varId, value.varvalue);
|
||||||
}
|
}
|
||||||
local = pm;
|
ProgramMemory local = pm;
|
||||||
fillProgramMemoryFromAssignments(pm, tok, local, vars);
|
fillProgramMemoryFromAssignments(pm, tok, local, vars);
|
||||||
replace(pm, tok);
|
replace(pm, tok);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue