| 3916 | } |
| 3917 | |
| 3918 | static void valueFlowForwardAssign(Token* const tok, |
| 3919 | const Token* expr, |
| 3920 | std::vector<const Variable*> vars, |
| 3921 | std::list<ValueFlow::Value> values, |
| 3922 | const bool init, |
| 3923 | const TokenList& tokenlist, |
| 3924 | ErrorLogger& errorLogger, |
| 3925 | const Settings& settings) |
| 3926 | { |
| 3927 | if (Token::simpleMatch(tok->astParent(), "return")) |
| 3928 | return; |
| 3929 | const Token* endOfVarScope = ValueFlow::getEndOfExprScope(expr); |
| 3930 | if (std::any_of(values.cbegin(), values.cend(), std::mem_fn(&ValueFlow::Value::isLifetimeValue))) { |
| 3931 | valueFlowForwardLifetime(tok, tokenlist, errorLogger, settings); |
| 3932 | values.remove_if(std::mem_fn(&ValueFlow::Value::isLifetimeValue)); |
| 3933 | } |
| 3934 | if (std::all_of( |
| 3935 | vars.cbegin(), vars.cend(), [&](const Variable* var) { |
| 3936 | return !var->isPointer() && !var->isSmartPointer(); |
| 3937 | })) |
| 3938 | values.remove_if(std::mem_fn(&ValueFlow::Value::isTokValue)); |
| 3939 | if (tok->astParent()) { |
| 3940 | for (ValueFlow::Value& value : values) { |
| 3941 | std::string valueKind; |
| 3942 | if (value.valueKind == ValueFlow::Value::ValueKind::Impossible) { |
| 3943 | if (value.bound == ValueFlow::Value::Bound::Point) |
| 3944 | valueKind = "never "; |
| 3945 | else if (value.bound == ValueFlow::Value::Bound::Lower) |
| 3946 | valueKind = "less than "; |
| 3947 | else if (value.bound == ValueFlow::Value::Bound::Upper) |
| 3948 | valueKind = "greater than "; |
| 3949 | } |
| 3950 | std::string info = "Assignment '" + tok->astParent()->expressionString() + "', assigned value is " + valueKind + value.infoString(); |
| 3951 | value.errorPath.emplace_back(tok, std::move(info)); |
| 3952 | } |
| 3953 | } |
| 3954 | |
| 3955 | if (tokenlist.isCPP() && vars.size() == 1 && Token::Match(vars.front()->typeStartToken(), "bool|_Bool")) { |
| 3956 | for (ValueFlow::Value& value : values) { |
| 3957 | if (value.isImpossible()) |
| 3958 | continue; |
| 3959 | if (value.isIntValue()) |
| 3960 | value.intvalue = (value.intvalue != 0); |
| 3961 | if (value.isTokValue()) |
| 3962 | value.intvalue = (value.tokvalue != nullptr); |
| 3963 | } |
| 3964 | } |
| 3965 | |
| 3966 | // Static variable initialisation? |
| 3967 | if (vars.size() == 1 && vars.front()->isStatic() && !vars.front()->isConst() && init) |
| 3968 | lowerToPossible(values); |
| 3969 | |
| 3970 | // is volatile |
| 3971 | if (std::any_of(vars.cbegin(), vars.cend(), [&](const Variable* var) { |
| 3972 | return var->isVolatile(); |
| 3973 | })) |
| 3974 | lowerToPossible(values); |
| 3975 |
no test coverage detected