let eval_binop_float ~with_alarms ev1 op ev2 =
try
let conv v =
try Ival.project_float (V.project_ival v)
with
| V.Not_based_on_null
| Ival.Float_abstract.Nan_or_infinite ->
warning_once_current "converting value to float: assert(Ook)";
Ival.Float_abstract.top
in
let f1 = conv ev1
and f2 = conv ev2
in
let binary_float_floats (_name: string) f =
try
let alarm, f = f (get_rounding_mode ()) f1 f2 in
if alarm then CilE.warn_result_nan_infinite with_alarms;
V.inject_ival (Ival.inject_float f)
with
| Ival.Float_abstract.Nan_or_infinite ->
CilE.warn_result_nan_infinite with_alarms ;
V.top_float
| Ival.Float_abstract.Bottom ->
CilE.warn_result_nan_infinite with_alarms ;
V.bottom
in
begin match op with
| PlusA -> binary_float_floats "+." Ival.Float_abstract.add_float
| MinusA -> binary_float_floats "-." Ival.Float_abstract.sub_float
| Mult -> binary_float_floats "*." Ival.Float_abstract.mult_float
| Div -> binary_float_floats "/." Ival.Float_abstract.div_float
| Eq ->
let contains_zero, contains_non_zero =
Ival.Float_abstract.equal_float_ieee f1 f2
in
V.interp_boolean ~contains_zero ~contains_non_zero
| Ne ->
let contains_non_zero, contains_zero =
Ival.Float_abstract.equal_float_ieee f1 f2
in
V.interp_boolean ~contains_zero ~contains_non_zero
| Lt ->
V.interp_boolean
~contains_zero:(Ival.Float_abstract.maybe_le_ieee_float f2 f1)
~contains_non_zero:(Ival.Float_abstract.maybe_lt_ieee_float f1 f2)
| Le ->
V.interp_boolean
~contains_zero:(Ival.Float_abstract.maybe_lt_ieee_float f2 f1)
~contains_non_zero:(Ival.Float_abstract.maybe_le_ieee_float f1 f2)
| Gt ->
V.interp_boolean
~contains_zero:(Ival.Float_abstract.maybe_le_ieee_float f1 f2)
~contains_non_zero:(Ival.Float_abstract.maybe_lt_ieee_float f2 f1)
| Ge ->
V.interp_boolean
~contains_zero:(Ival.Float_abstract.maybe_lt_ieee_float f1 f2)
~contains_non_zero:(Ival.Float_abstract.maybe_le_ieee_float f2 f1)
| _ -> raise V.Not_based_on_null
end
with V.Not_based_on_null | Ival.F.Nan_or_infinite ->
warning_once_current
"float operation on address.";
V.join
(V.topify_arith_origin ev1)
(V.topify_arith_origin ev2)