(
&mut self,
value: Rc<SymbolicValue>,
expected: bool,
abstract_value: &AbstractDomain<DomainType>,
)
| 238 | } |
| 239 | |
| 240 | fn check_overflow( |
| 241 | &mut self, |
| 242 | value: Rc<SymbolicValue>, |
| 243 | expected: bool, |
| 244 | abstract_value: &AbstractDomain<DomainType>, |
| 245 | ) -> CheckerResult { |
| 246 | match &value.expression { |
| 247 | Expression::CompileTimeConstant(ConstantValue::Int(constant)) => { |
| 248 | if constant == &Integer::from(expected) { |
| 249 | CheckerResult::Safe |
| 250 | } else { |
| 251 | CheckerResult::Unsafe |
| 252 | } |
| 253 | } |
| 254 | Expression::Variable { path, var_type } => { |
| 255 | assert_eq!(*var_type, ExpressionType::Bool); |
| 256 | match &path.value { |
| 257 | // Overflow operand is a qualified path, meaning that it is the compiler generated bit indicating overflow: `path.1` |
| 258 | // The value is in `path.0`, so we construct it manually and test whether its value is possibly an overflow |
| 259 | PathEnum::QualifiedPath { |
| 260 | length: _, |
| 261 | qualifier, |
| 262 | selector, |
| 263 | } => { |
| 264 | if Rc::new(PathSelector::Field(1)) != *selector { |
| 265 | CheckerResult::Warning |
| 266 | } else { |
| 267 | let new_path = Path::new_field(qualifier.clone(), 0); |
| 268 | if let Some(&rustc_type) = |
| 269 | self.body_visitor.type_visitor.path_ty_cache.get(&new_path) |
| 270 | { |
| 271 | self.check_within_range(new_path, rustc_type, abstract_value) |
| 272 | } else { |
| 273 | CheckerResult::Warning |
| 274 | } |
| 275 | } |
| 276 | } |
| 277 | _ => { |
| 278 | // Overflow operand is not a qualified path, meaning that we can test it directly |
| 279 | self.check_assert_condition(value, expected, abstract_value) |
| 280 | } |
| 281 | } |
| 282 | } |
| 283 | _ => self.check_assert_condition(value, expected, abstract_value), |
| 284 | } |
| 285 | } |
| 286 | } |
no test coverage detected