@@ -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
@@ -280,7 +293,7 @@ struct
280293 let rec addToOffset n (t :typ option ) = function
281294 | `Index (i , `NoOffset) ->
282295 (* Binary operations on pointer types should not generate warnings in SV-COMP *)
283- GobRef. wrap AnalysisState. executing_speculative_computations true @@ fun () ->
296+ let @ () = GobRef. wrap AnalysisState. executing_speculative_computations true in
284297 (* If we have arrived at the last Offset and it is an Index, we add our integer to it *)
285298 `Index (IdxDom. add i (iDtoIdx n), `NoOffset )
286299 | `Field (f , `NoOffset) ->
@@ -332,7 +345,10 @@ struct
332345 (* Pointer subtracted by a value (e-i) is very similar *)
333346 (* Cast n to the (signed) ptrdiff_ikind, then add the its negated value. *)
334347 | MinusPI ->
335- let n = ID. neg (ID. cast_to ~kind: Internal (Cilfacade. ptrdiff_ikind () ) n) in (* TODO: proper castkind *)
348+ let n = (* only speculative during ID.neg *)
349+ let @ () = GobRef. wrap AnalysisState. executing_speculative_computations true in
350+ ID. neg (ID. cast_to ~kind: Internal (Cilfacade. ptrdiff_ikind () ) n) (* TODO: proper castkind *)
351+ in
336352 Address (ad_concat_map (addToAddr n) p)
337353 | Mod -> Int (ID. top_of (Cilfacade. ptrdiff_ikind () )) (* we assume that address is actually casted to int first*)
338354 | _ -> Address AD. top_ptr
@@ -346,7 +362,8 @@ struct
346362 (* For the float values, we apply the float domain operators *)
347363 | Float v1 , Float v2 when is_int_returning_binop_FD op ->
348364 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 *)
365+ assert (result_ik = IInt );
366+ Int (fd_binary_pred (int_returning_binop_FD op v1 v2))
350367 | Float v1 , Float v2 -> Float (binop_FD (Cilfacade. get_fkind t) op v1 v2)
351368 (* For address +/- value, we try to do some elementary ptr arithmetic *)
352369 | Address p, Int n
@@ -929,11 +946,8 @@ struct
929946 Address (AD. map array_start (eval_lv ~man st lval))
930947 | CastE (_ , t , Const (CStr (x ,e ))) -> (* VD.top () *) eval_rv ~man st (Const (CStr (x,e))) (* TODO safe? *)
931948 | CastE (kind , t , exp ) ->
932- (let v = eval_rv ~man st exp in
933- try
934- VD. cast ~kind ~torg: (Cilfacade. typeOf exp) t v
935- with Cilfacade. TypeOfError _ ->
936- VD. cast ~kind t v)
949+ let v = eval_rv ~man st exp in
950+ VD. cast ~kind t v
937951 | SizeOf _
938952 | Real _
939953 | Imag _
@@ -2061,7 +2075,7 @@ struct
20612075 if not (ThreadIdDomain.Thread. is_main tid) then ( (* Only non-main return constitutes an implicit pthread_exit according to man page (https://github.com/goblint/analyzer/issues/1767#issuecomment-3642590227). *)
20622076 (* Evaluate exp and cast the resulting value to the void-pointer-type.
20632077 Casting to the right type here avoids precision loss on joins. *)
2064- let rv = VD. cast ~kind: Internal ~torg: ( Cilfacade. typeOf exp) Cil. voidPtrType rv in (* TODO: proper castkind *)
2078+ let rv = VD. cast ~kind: Internal Cil. voidPtrType rv in (* TODO: proper castkind *)
20652079 man.sideg (V. thread tid) (G. create_thread rv)
20662080 );
20672081 Priv. thread_return ask (priv_getg man.global) (priv_sideg man.sideg) tid st'
@@ -2648,7 +2662,8 @@ struct
26482662 | _, None
26492663 | None , _ -> ID. top_of ik
26502664 | Some mx , Some mm when Z. equal mx mm -> ID. top_of ik
2651- | _ , _ ->
2665+ | _ , _ -> (* ID.neg will not overflow *)
2666+ let @ () = GobRef. wrap AnalysisState. executing_speculative_computations true in (* ID.neg is our internal implementation of abs *)
26522667 let x1 = ID. neg (ID. meet (ID. ending ik Z. zero) xcast) in
26532668 let x2 = ID. meet (ID. starting ik Z. zero) xcast in
26542669 ID. join x1 x2
@@ -2661,11 +2676,11 @@ struct
26612676 | Nan (fk , str ) when Cil. isPointerType (Cilfacade. typeOf str) -> Float (FD. nan_of fk)
26622677 | Nan _ -> failwith (" non-pointer argument in call to function " ^ f.vname)
26632678 | 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 * )
2679+ | Isfinite x -> Int (fd_unary_pred (apply_unary FDouble FD. isfinite x))
2680+ | Isinf x -> Int (fd_unary_pred (apply_unary FDouble FD. isinf x))
2681+ | Isnan x -> Int (fd_unary_pred (apply_unary FDouble FD. isnan x))
2682+ | Isnormal x -> Int (fd_unary_pred (apply_unary FDouble FD. isnormal x))
2683+ | Signbit x -> Int (fd_unary_pred (apply_unary FDouble FD. signbit x))
26692684 | Ceil (fk ,x ) -> Float (apply_unary fk FD. ceil x)
26702685 | Floor (fk ,x ) -> Float (apply_unary fk FD. floor x)
26712686 | Fabs (fk , x ) -> Float (apply_unary fk FD. fabs x)
@@ -2676,12 +2691,12 @@ struct
26762691 | Cos (fk , x ) -> Float (apply_unary fk FD. cos x)
26772692 | Sin (fk , x ) -> Float (apply_unary fk FD. sin x)
26782693 | 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 * )
2694+ | Isgreater (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. gt x y))
2695+ | Isgreaterequal (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. ge x y))
2696+ | Isless (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. lt x y))
2697+ | Islessequal (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. le x y))
2698+ | 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)))
2699+ | Isunordered (x ,y ) -> Int (fd_binary_pred (apply_binary FDouble FD. unordered x y))
26852700 | Fmax (fd , x ,y ) -> Float (apply_binary fd FD. fmax x y)
26862701 | Fmin (fd , x ,y ) -> Float (apply_binary fd FD. fmin x y)
26872702 | Sqrt (fk , x ) -> Float (apply_unary fk FD. sqrt x)
0 commit comments