Skip to content

Commit

Permalink
Use ProgramMemory
Browse files Browse the repository at this point in the history
  • Loading branch information
chrchr-github committed Jul 15, 2023
1 parent 02f7818 commit ba9f8a5
Showing 1 changed file with 48 additions and 42 deletions.
90 changes: 48 additions & 42 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5619,52 +5619,58 @@ static void valueFlowForwardConst(Token* start,
{
if (!precedes(start, end))
throw InternalError(var->nameToken(), "valueFlowForwardConst: start token does not precede the end token.");
for (Token* tok = start; tok != end; tok = tok->next()) {
if (tok->varId() == var->declarationId()) {
for (const ValueFlow::Value& value : values) {
if (std::any_of(tok->values().begin(), tok->values().end(), [&value](const ValueFlow::Value& v) {
return v.isImpossible() && v.condition && v.valueType == ValueFlow::Value::ValueType::INT && v.valueType == value.valueType;
}))
continue;
for (const ValueFlow::Value& value : values) {
ProgramMemory pm;
pm.setValue(var->nameToken(), value);

for (Token* tok = start; tok != end; tok = tok->next()) {
if (tok->varId() == var->declarationId()) {
if (tok->scope()->type == Scope::ScopeType::eIf) {
MathLib::bigint result{};
bool error{};
execute(tok->scope()->bodyStart->linkAt(-1), pm, &result, &error, settings);
if (!result || error)
continue;
}
setTokenValue(tok, value, settings);
}
} else {
[&] {
// Follow references
auto refs = followAllReferences(tok);
auto it = std::find_if(refs.cbegin(), refs.cend(), [&](const ReferenceToken& ref) {
return ref.token->varId() == var->declarationId();
});
if (it != refs.end()) {
for (ValueFlow::Value value : values) {
if (refs.size() > 1)
value.setInconclusive();
value.errorPath.insert(value.errorPath.end(), it->errors.cbegin(), it->errors.cend());
setTokenValue(tok, std::move(value), settings);
} else {
[&] {
// Follow references
auto refs = followAllReferences(tok);
auto it = std::find_if(refs.cbegin(), refs.cend(), [&](const ReferenceToken& ref) {
return ref.token->varId() == var->declarationId();
});
if (it != refs.end()) {
for (ValueFlow::Value value : values) {
if (refs.size() > 1)
value.setInconclusive();
value.errorPath.insert(value.errorPath.end(), it->errors.cbegin(), it->errors.cend());
setTokenValue(tok, std::move(value), settings);
}
return;
}
return;
}
// Follow symbolic values
for (const ValueFlow::Value& v : tok->values()) {
if (!v.isSymbolicValue())
continue;
if (!v.tokvalue)
continue;
if (v.tokvalue->varId() != var->declarationId())
continue;
for (ValueFlow::Value value : values) {
if (v.intvalue != 0) {
if (!value.isIntValue())
continue;
value.intvalue += v.intvalue;
// Follow symbolic values
for (const ValueFlow::Value& v : tok->values()) {
if (!v.isSymbolicValue())
continue;
if (!v.tokvalue)
continue;
if (v.tokvalue->varId() != var->declarationId())
continue;
for (ValueFlow::Value value : values) {
if (v.intvalue != 0) {
if (!value.isIntValue())
continue;
value.intvalue += v.intvalue;
}
value.valueKind = v.valueKind;
value.bound = v.bound;
value.errorPath.insert(value.errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend());
setTokenValue(tok, std::move(value), settings);
}
value.valueKind = v.valueKind;
value.bound = v.bound;
value.errorPath.insert(value.errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend());
setTokenValue(tok, std::move(value), settings);
}
}
}();
}();
}
}
}
}
Expand Down

0 comments on commit ba9f8a5

Please sign in to comment.