diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 2ec6ae8c6af..81f0d520903 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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); } - } - }(); + }(); + } } } }