| 3810 | */ |
| 3811 | template<class ContainerOfValue> |
| 3812 | static void valueFlowForwardConst(Token* start, |
| 3813 | const Token* end, |
| 3814 | const Variable* var, |
| 3815 | const ContainerOfValue& values, |
| 3816 | const Settings& settings, |
| 3817 | int /*unused*/ = 0) |
| 3818 | { |
| 3819 | if (!precedes(start, end)) |
| 3820 | throw InternalError(var->nameToken(), "valueFlowForwardConst: start token does not precede the end token."); |
| 3821 | for (Token* tok = start; tok != end; tok = tok->next()) { |
| 3822 | if (tok->varId() == var->declarationId()) { |
| 3823 | for (const ValueFlow::Value& value : values) |
| 3824 | setTokenValue(tok, value, settings); |
| 3825 | } else { |
| 3826 | [&] { |
| 3827 | // Follow references |
| 3828 | const auto& refs = tok->refs(); |
| 3829 | auto it = std::find_if(refs.cbegin(), refs.cend(), [&](const ReferenceToken& ref) { |
| 3830 | return ref.token->varId() == var->declarationId(); |
| 3831 | }); |
| 3832 | if (it != refs.end()) { |
| 3833 | for (ValueFlow::Value value : values) { |
| 3834 | if (refs.size() > 1) |
| 3835 | value.setInconclusive(); |
| 3836 | value.errorPath.insert(value.errorPath.end(), it->errors.cbegin(), it->errors.cend()); |
| 3837 | setTokenValue(tok, std::move(value), settings); |
| 3838 | } |
| 3839 | return; |
| 3840 | } |
| 3841 | // Follow symbolic values |
| 3842 | for (const ValueFlow::Value& v : tok->values()) { |
| 3843 | if (!v.isSymbolicValue()) |
| 3844 | continue; |
| 3845 | if (!v.tokvalue) |
| 3846 | continue; |
| 3847 | if (v.tokvalue->varId() != var->declarationId()) |
| 3848 | continue; |
| 3849 | for (ValueFlow::Value value : values) { |
| 3850 | if (!v.isKnown() && value.isImpossible()) |
| 3851 | continue; |
| 3852 | if (v.intvalue != 0) { |
| 3853 | if (!value.isIntValue()) |
| 3854 | continue; |
| 3855 | value.intvalue += v.intvalue; |
| 3856 | } |
| 3857 | if (!value.isImpossible()) |
| 3858 | value.valueKind = v.valueKind; |
| 3859 | value.bound = v.bound; |
| 3860 | value.errorPath.insert(value.errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend()); |
| 3861 | setTokenValue(tok, std::move(value), settings); |
| 3862 | } |
| 3863 | } |
| 3864 | }(); |
| 3865 | } |
| 3866 | } |
| 3867 | } |
| 3868 | |
| 3869 | static void valueFlowForwardConst(Token* start, |
no test coverage detected