@@ -169,14 +169,27 @@ struct
169169
170170 let iDtoIdx x = ID. cast_to ~kind: Internal (Cilfacade. ptrdiff_ikind () ) x (* TODO: proper castkind *)
171171
172+ (* * Unary float predicates return non-zero for [true].
173+ @see C11 7.12.3 *)
174+ let fd_unary_pred = function
175+ | Some true -> ID. of_excl_list IInt [Z. zero]
176+ | Some false -> ID. of_int IInt Z. zero
177+ | None -> ID. top_of IInt
178+
179+ (* * Binary float predicates return one for [true].
180+ @see C11 7.12.14, 6.5.8, 6.5.9 *)
181+ let fd_binary_pred = function
182+ | Some b -> ID. of_bool IInt b
183+ | None -> ID. top_of IInt
184+
172185 let unop_ID = function
173186 | Neg -> ID. neg
174187 | BNot -> ID. lognot
175188 | LNot -> ID. c_lognot
176189
177190 let unop_FD = function
178191 | Neg -> (fun v -> (Float (FD. neg v):value))
179- | LNot -> (fun c -> Int (FD. eq c (FD. of_const (FD. get_fkind c) 0. )))
192+ | LNot -> (fun c -> Int (fd_unary_pred ( FD. eq c (FD. of_const (FD. get_fkind c) 0. ) )))
180193 | BNot -> failwith " BNot on a value of type float!"
181194
182195
@@ -256,7 +269,7 @@ struct
256269 | Ge -> FD. ge
257270 | Eq -> FD. eq
258271 | Ne -> FD. ne
259- | _ -> (fun _ _ -> ID. top () )
272+ | _ -> (fun _ _ -> None )
260273
261274 let is_int_returning_binop_FD = function
262275 | Lt | Gt | Le | Ge | Eq | Ne -> true
@@ -346,7 +359,8 @@ struct
346359 (* For the float values, we apply the float domain operators *)
347360 | Float v1 , Float v2 when is_int_returning_binop_FD op ->
348361 let result_ik = Cilfacade. get_ikind t in
349- Int (ID. cast_to ~kind: Internal result_ik (int_returning_binop_FD op v1 v2)) (* TODO: proper castkind *)
362+ assert (result_ik = IInt );
363+ Int (fd_binary_pred (int_returning_binop_FD op v1 v2))
350364 | Float v1 , Float v2 -> Float (binop_FD (Cilfacade. get_fkind t) op v1 v2)
351365 (* For address +/- value, we try to do some elementary ptr arithmetic *)
352366 | Address p, Int n
@@ -2661,11 +2675,11 @@ struct
26612675 | Nan (fk , str ) when Cil. isPointerType (Cilfacade. typeOf str) -> Float (FD. nan_of fk)
26622676 | Nan _ -> failwith (" non-pointer argument in call to function " ^ f.vname)
26632677 | Inf fk -> Float (FD. inf_of fk)
2664- | Isfinite x -> Int (ID. cast_to ~kind: Internal IInt (apply_unary FDouble FD. isfinite x)) (* TODO: proper castkind * )
2665- | Isinf x -> Int (ID. cast_to ~kind: Internal IInt (apply_unary FDouble FD. isinf x)) (* TODO: proper castkind * )
2666- | Isnan x -> Int (ID. cast_to ~kind: Internal IInt (apply_unary FDouble FD. isnan x)) (* TODO: proper castkind * )
2667- | Isnormal x -> Int (ID. cast_to ~kind: Internal IInt (apply_unary FDouble FD. isnormal x)) (* TODO: proper castkind * )
2668- | Signbit x -> Int (ID. cast_to ~kind: Internal IInt (apply_unary FDouble FD. signbit x)) (* TODO: proper castkind * )
2678+ | Isfinite x -> Int (fd_unary_pred (apply_unary FDouble FD. isfinite x))
2679+ | Isinf x -> Int (fd_unary_pred (apply_unary FDouble FD. isinf x))
2680+ | Isnan x -> Int (fd_unary_pred (apply_unary FDouble FD. isnan x))
2681+ | Isnormal x -> Int (fd_unary_pred (apply_unary FDouble FD. isnormal x))
2682+ | Signbit x -> Int (fd_unary_pred (apply_unary FDouble FD. signbit x))
26692683 | Ceil (fk ,x ) -> Float (apply_unary fk FD. ceil x)
26702684 | Floor (fk ,x ) -> Float (apply_unary fk FD. floor x)
26712685 | Fabs (fk , x ) -> Float (apply_unary fk FD. fabs x)
@@ -2676,12 +2690,12 @@ struct
26762690 | Cos (fk , x ) -> Float (apply_unary fk FD. cos x)
26772691 | Sin (fk , x ) -> Float (apply_unary fk FD. sin x)
26782692 | Tan (fk , x ) -> Float (apply_unary fk FD. tan x)
2679- | Isgreater (x ,y ) -> Int (ID. cast_to ~kind: Internal IInt (apply_binary FDouble FD. gt x y)) (* TODO: proper castkind * )
2680- | Isgreaterequal (x ,y ) -> Int (ID. cast_to ~kind: Internal IInt (apply_binary FDouble FD. ge x y)) (* TODO: proper castkind * )
2681- | Isless (x ,y ) -> Int (ID. cast_to ~kind: Internal IInt (apply_binary FDouble FD. lt x y)) (* TODO: proper castkind * )
2682- | Islessequal (x ,y ) -> Int (ID. cast_to ~kind: Internal IInt (apply_binary FDouble FD. le x y)) (* TODO: proper castkind * )
2683- | Islessgreater (x ,y ) -> Int (ID. c_logor (ID. cast_to ~kind: Internal IInt (apply_binary FDouble FD. lt x y)) (ID. cast_to ~kind: Internal IInt (apply_binary FDouble FD. gt x y))) (* TODO: proper castkind * )
2684- | Isunordered (x ,y ) -> Int (ID. cast_to ~kind: Internal IInt (apply_binary FDouble FD. unordered x y)) (* TODO: proper castkind * )
2693+ | Isgreater (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. gt x y))
2694+ | Isgreaterequal (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. ge x y))
2695+ | Isless (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. lt x y))
2696+ | Islessequal (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. le x y))
2697+ | Islessgreater (x ,y ) -> Int (ID. c_logor (fd_binary_pred (apply_binary FDouble FD. lt x y)) (fd_binary_pred (apply_binary FDouble FD. gt x y)))
2698+ | Isunordered (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. unordered x y))
26852699 | Fmax (fd , x ,y ) -> Float (apply_binary fd FD. fmax x y)
26862700 | Fmin (fd , x ,y ) -> Float (apply_binary fd FD. fmin x y)
26872701 | Sqrt (fk , x ) -> Float (apply_unary fk FD. sqrt x)
0 commit comments