| 1067 | } |
| 1068 | |
| 1069 | static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& settings) |
| 1070 | { |
| 1071 | for (Token* tok = tokenList.front(); tok; tok = tok->next()) { |
| 1072 | if (tok->hasKnownIntValue()) |
| 1073 | continue; |
| 1074 | if (Token::Match(tok, "%bool%")) |
| 1075 | continue; |
| 1076 | if (astIsBool(tok) || Token::Match(tok, "%comp%")) { |
| 1077 | ValueFlow::Value lower{-1}; |
| 1078 | lower.bound = ValueFlow::Value::Bound::Upper; |
| 1079 | lower.setImpossible(); |
| 1080 | setTokenValue(tok, std::move(lower), settings); |
| 1081 | |
| 1082 | ValueFlow::Value upper{2}; |
| 1083 | upper.bound = ValueFlow::Value::Bound::Lower; |
| 1084 | upper.setImpossible(); |
| 1085 | setTokenValue(tok, std::move(upper), settings); |
| 1086 | } else if (astIsUnsigned(tok) && !astIsPointer(tok)) { |
| 1087 | std::vector<MathLib::bigint> minvalue = minUnsignedValue(tok); |
| 1088 | if (minvalue.empty()) |
| 1089 | continue; |
| 1090 | ValueFlow::Value value{std::max<MathLib::bigint>(0, minvalue.front()) - 1}; |
| 1091 | value.bound = ValueFlow::Value::Bound::Upper; |
| 1092 | value.setImpossible(); |
| 1093 | setTokenValue(tok, std::move(value), settings); |
| 1094 | } |
| 1095 | if (Token::simpleMatch(tok, "?") && Token::Match(tok->astOperand1(), "<|<=|>|>=")) { |
| 1096 | const Token* condTok = tok->astOperand1(); |
| 1097 | const Token* branchesTok = tok->astOperand2(); |
| 1098 | |
| 1099 | auto tokens = makeArray(condTok->astOperand1(), condTok->astOperand2()); |
| 1100 | auto branches = makeArray(branchesTok->astOperand1(), branchesTok->astOperand2()); |
| 1101 | bool flipped = false; |
| 1102 | if (std::equal(tokens.cbegin(), tokens.cend(), branches.crbegin(), &isSameToken)) |
| 1103 | flipped = true; |
| 1104 | else if (!std::equal(tokens.cbegin(), tokens.cend(), branches.cbegin(), &isSameToken)) |
| 1105 | continue; |
| 1106 | std::vector<ValueFlow::Value> values; |
| 1107 | for (const Token* tok2 : tokens) { |
| 1108 | if (const ValueFlow::Value* v = tok2->getKnownValue(ValueFlow::Value::ValueType::INT)) { |
| 1109 | values.emplace_back(*v); |
| 1110 | } else { |
| 1111 | ValueFlow::Value symValue{}; |
| 1112 | symValue.valueType = ValueFlow::Value::ValueType::SYMBOLIC; |
| 1113 | symValue.tokvalue = tok2; |
| 1114 | values.push_back(std::move(symValue)); |
| 1115 | std::copy_if(tok2->values().cbegin(), |
| 1116 | tok2->values().cend(), |
| 1117 | std::back_inserter(values), |
| 1118 | [](const ValueFlow::Value& v) { |
| 1119 | if (!v.isKnown()) |
| 1120 | return false; |
| 1121 | return v.isSymbolicValue(); |
| 1122 | }); |
| 1123 | } |
| 1124 | } |
| 1125 | const bool isMin = Token::Match(condTok, "<|<=") ^ flipped; |
| 1126 | for (ValueFlow::Value& value : values) { |
no test coverage detected