Skip to content

Commit d505a38

Browse files
authored
Merge pull request #1906 from goblint/float-predicates
Simplify return type of `FloatDomain` predicates
2 parents 2326a84 + 74711c1 commit d505a38

File tree

5 files changed

+173
-174
lines changed

5 files changed

+173
-174
lines changed

src/analyses/base.ml

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)