@@ -25,12 +25,16 @@ module Enums : S with type int_t = Z.t = struct
2525 let top_of ?bitfield ik =
2626 match ik with
2727 | IBool -> top_bool
28- | _ -> match bitfield with
29- | Some b when b < = Z. numbits(Size. range ik |> snd) ->
30- Exc (BISet. empty () , match Cil. isSigned ik with
31- | true -> R. of_interval range_ikind (Int64. of_int @@ - (b-1 ), Int64. of_int b)
32- | false -> R. of_interval range_ikind (Int64. of_int 0 , Int64. of_int b)
33- )
28+ | _ ->
29+ match bitfield with
30+ | Some b when b < = Z. numbits (Size. range ik |> snd) ->
31+ let range =
32+ if Cil. isSigned ik then
33+ R. of_interval range_ikind (Int64. of_int @@ - (b - 1 ), Int64. of_int b)
34+ else
35+ R. of_interval range_ikind (Int64. of_int 0 , Int64. of_int b)
36+ in
37+ Exc (BISet. empty () , range)
3438 | _ -> Exc (BISet. empty () , size ik)
3539
3640 let range ik = Size. range ik
@@ -217,101 +221,113 @@ module Enums : S with type int_t = Z.t = struct
217221 let rem = lift2 Z. rem
218222
219223 let apply_range f r = (* apply f to the min/max of the old range r to get a new range *)
220- (* If the Int64 might overflow on us during computation, we instead go to top_range *)
221- match R. minimal r, R. maximal r with
222- | _ ->
223- let rf m = (size % Size. min_for % f) (m r) in
224- let r1, r2 = rf Exclusion. min_of_range, rf Exclusion. max_of_range in
225- R. join r1 r2
224+ let rf m = (size % Size. min_for % f) (m r) in
225+ let r1, r2 = rf Exclusion. min_of_range, rf Exclusion. max_of_range in
226+ R. join r1 r2
226227
227228 let lognot ikind v = norm ikind @@ match v with
228- | Inc x when BISet. is_empty x -> v
229+ | Inc x when BISet. is_empty x -> v
229230 | Inc x when BISet. is_singleton x -> Inc (BISet. singleton (Z. lognot (BISet. choose x)))
230- | Inc x -> Inc (BISet. map Z. lognot x)
231- | Exc (s ,r ) ->
231+ | Inc x -> Inc (BISet. map Z. lognot x) (* TODO: don't operate on Inc? *)
232+ | Exc (s , r ) ->
232233 let s' = BISet. map Z. lognot s in
233234 let r' = match R. minimal r, R. maximal r with
234- | Some min , Some max -> R. of_interval range_ikind (Int64. neg max, Int64. neg min)
235- | _ -> apply_range Z. lognot r
235+ | Some min , Some max -> R. of_interval range_ikind (Int64. neg max, Int64. neg min) (* TODO: why missing conditions compared to DefExc lognot? *)
236+ | _ , _ -> apply_range Z. lognot r
236237 in
237238 Exc (s', r')
238239
239- let logand ikind u v =
240- handle_bot u v (fun () ->
241- norm ikind @@ match u, v with
242- | Inc x ,Inc y when BISet. is_singleton x && BISet. is_singleton y -> Inc (BISet. singleton (Z. logand (BISet. choose x) (BISet. choose y)))
243- | Inc x, Exc (s,r)
244- | Exc (s ,r ), Inc x ->
245- let f = fun i ->
246- (match (R. minimal r, R. maximal r) with
247- | (None , _ ) | (_ , None) -> R. top_of ikind
248- | (Some r1 , Some r2 ) ->
249- match Z. compare i Z. zero > = 0 , Int64. compare r1 Int64. zero > = 0 with
250- | true , true -> R. of_interval range_ikind (Int64. zero, Int64. min r2 (Int64. of_int @@ Z. numbits i))
251- | true , _ -> R. of_interval range_ikind (Int64. zero, Int64. of_int @@ Z. numbits i)
252- | _ , true -> R. of_interval range_ikind (Int64. zero, r2)
253- | _ , _ -> let b = Int64. max (Int64. of_int @@ Z. numbits i) (Int64. max (Int64. abs r1) (Int64. abs r2)) in
254- R. of_interval range_ikind (Int64. neg b, b)
255- ) in
256- let r' = BISet. fold (fun i acc -> R. join (f i) acc) x (R. bot () ) in
257- Exc (BISet. empty () , r')
258- | Exc (_ , p ), Exc (_ , r ) ->
259- (match R. minimal p, R. maximal p, R. minimal r, R. maximal r with
260- | Some p1 , Some p2 , Some r1 , Some r2 -> begin
261- match Int64. compare p1 Int64. zero > = 0 , Int64. compare r1 Int64. zero > = 0 with
262- | true , true -> Exc (BISet. empty () , R. of_interval range_ikind (Int64. zero, Int64. min p2 r2))
263- | true , _ -> Exc (BISet. empty () , R. of_interval range_ikind (Int64. zero, p2))
264- | _ , true -> Exc (BISet. empty () , R. of_interval range_ikind (Int64. zero, r2))
265- | _ -> Exc (BISet. empty () , R. join p r)
266- end
267- | _ -> top_of ikind)
268- | _ ,_ -> top_of ikind)
240+ let logand ikind u v = handle_bot u v (fun () ->
241+ norm ikind @@ match u, v with
242+ | Inc x , Inc y when BISet. is_singleton x && BISet. is_singleton y ->
243+ Inc (BISet. singleton (Z. logand (BISet. choose x) (BISet. choose y)))
244+ | Inc x, Exc (s, r)
245+ | Exc (s , r ), Inc x ->
246+ let f i =
247+ match R. minimal r, R. maximal r with
248+ | None , _
249+ | _ , None -> R. top_of ikind
250+ | Some r1 , Some r2 ->
251+ match Z. compare i Z. zero > = 0 , Int64. compare r1 Int64. zero > = 0 with
252+ | true , true -> R. of_interval range_ikind (Int64. zero, Int64. min r2 (Int64. of_int @@ Z. numbits i))
253+ | true , _ -> R. of_interval range_ikind (Int64. zero, Int64. of_int @@ Z. numbits i)
254+ | _ , true -> R. of_interval range_ikind (Int64. zero, r2)
255+ | _ , _ ->
256+ let b = Int64. max (Int64. of_int @@ Z. numbits i) (Int64. max (Int64. abs r1) (Int64. abs r2)) in
257+ R. of_interval range_ikind (Int64. neg b, b)
258+ in
259+ let r' = BISet. fold (fun i acc -> R. join (f i) acc) x (R. bot () ) in
260+ Exc (BISet. empty () , r')
261+ | Exc (_ , p ), Exc (_ , r ) ->
262+ begin match R. minimal p, R. maximal p, R. minimal r, R. maximal r with
263+ | Some p1 , Some p2 , Some r1 , Some r2 ->
264+ begin match Int64. compare p1 Int64. zero > = 0 , Int64. compare r1 Int64. zero > = 0 with
265+ | true , true -> Exc (BISet. empty () , R. of_interval range_ikind (Int64. zero, Int64. min p2 r2))
266+ | true , _ -> Exc (BISet. empty () , R. of_interval range_ikind (Int64. zero, p2))
267+ | _ , true -> Exc (BISet. empty () , R. of_interval range_ikind (Int64. zero, r2))
268+ | _ , _ -> Exc (BISet. empty () , R. join p r)
269+ end
270+ | _ -> top_of ikind
271+ end
272+ | _ , _ -> top_of ikind
273+ )
269274
270- let logor ikind u v = handle_bot u v (fun () ->
275+ let logor ikind u v = handle_bot u v (fun () ->
271276 norm ikind @@ match u, v with
272- | Inc x ,Inc y when BISet. is_singleton x && BISet. is_singleton y -> Inc (BISet. singleton (Z. logor (BISet. choose x) (BISet. choose y)))
273- | Inc x, Exc (_,r)
274- | Exc (_ ,r ), Inc x ->
275- let f = fun i ->
277+ | Inc x , Inc y when BISet. is_singleton x && BISet. is_singleton y ->
278+ Inc (BISet. singleton (Z. logor (BISet. choose x) (BISet. choose y)))
279+ | Inc x, Exc (_, r)
280+ | Exc (_ , r ), Inc x ->
281+ let f i =
276282 if Z. compare i Z. zero > = 0 then
277283 R. join r (R. of_interval range_ikind (Int64. zero, Int64. of_int @@ Z. numbits i))
278- else
279- (match R. minimal r, R. maximal r with
280- | None , _ | _ , None -> R. top_of ikind
281- | Some r1 , Some r2 -> let b = Int64. max (Int64. of_int @@ Z. numbits i) (Int64. max (Int64. abs r1) (Int64. abs r2)) in
282- R. of_interval range_ikind (Int64. neg b, b)
283- ) in
284+ else (
285+ match R. minimal r, R. maximal r with
286+ | None , _
287+ | _ , None -> R. top_of ikind
288+ | Some r1 , Some r2 ->
289+ let b = Int64. max (Int64. of_int @@ Z. numbits i) (Int64. max (Int64. abs r1) (Int64. abs r2)) in
290+ R. of_interval range_ikind (Int64. neg b, b)
291+ )
292+ in
284293 let r' = BISet. fold (fun i acc -> R. join (f i) acc) x (R. bot () ) in
285294 Exc (BISet. empty () , r')
286295 | Exc (_ , r1 ), Exc (_ , r2 ) -> Exc (BISet. empty () , R. join r1 r2)
287- | _ -> top_of ikind)
296+ | _ -> top_of ikind
297+ )
288298
289299 let logxor ikind u v = handle_bot u v (fun () ->
290300 norm ikind @@ match u, v with
291- | Inc x ,Inc y when BISet. is_singleton x && BISet. is_singleton y -> Inc (BISet. singleton (Z. logxor (BISet. choose x) (BISet. choose y)))
292- | Inc x, Exc (_,r)
293- | Exc (_ ,r ), Inc x ->
294- let f = fun i ->
301+ | Inc x , Inc y when BISet. is_singleton x && BISet. is_singleton y ->
302+ Inc (BISet. singleton (Z. logxor (BISet. choose x) (BISet. choose y)))
303+ | Inc x, Exc (_, r)
304+ | Exc (_ , r ), Inc x ->
305+ let f i =
295306 match R. minimal r, R. maximal r with
296- | None , _ | _ , None -> R. top_of ikind
297- | Some r1 , Some r2 -> let b = Int64. max (Int64. of_int @@ Z. numbits i) (Int64. max (Int64. abs r1) (Int64. abs r2)) in
307+ | None , _
308+ | _ , None -> R. top_of ikind
309+ | Some r1 , Some r2 ->
310+ let b = Int64. max (Int64. of_int @@ Z. numbits i) (Int64. max (Int64. abs r1) (Int64. abs r2)) in
298311 if Int64. compare r1 Int64. zero > = 0 && Z. compare i Z. zero > = 0 then
299312 R. of_interval range_ikind (Int64. zero, b)
300- else
313+ else
301314 R. of_interval range_ikind (Int64. neg b, b)
302- in
303- let r' = BISet. fold (fun i acc -> R. join (f i) acc) x (R. bot () ) in
315+ in
316+ let r' = BISet. fold (fun i acc -> R. join (f i) acc) x (R. bot () ) in
304317 Exc (BISet. empty () , r')
305- | Exc (_ , p ), Exc (_ , r ) -> begin
306- match R. minimal p, R. maximal p, R. minimal r, R. maximal r with
307- | Some p1 , Some p2 , Some r1 , Some r2 -> let b = List. fold_left Int64. max Int64. zero ( List. map Int64. abs [p1;p2;r1;r2]) in
308- if Int64. compare p1 Int64. zero > = 0 && Int64. compare r1 Int64. zero > = 0 then
318+ | Exc (_ , p ), Exc (_ , r ) ->
319+ begin match R. minimal p, R. maximal p, R. minimal r, R. maximal r with
320+ | Some p1 , Some p2 , Some r1 , Some r2 ->
321+ if Int64. compare p1 Int64. zero > = 0 && Int64. compare r1 Int64. zero > = 0 then
309322 Exc (BISet. empty () , R. of_interval range_ikind (Int64. zero, Int64. max p2 r2))
310- else
323+ else (
324+ let b = List. fold_left Int64. max Int64. zero (List. map Int64. abs [p1; p2; r1; r2]) in
311325 Exc (BISet. empty () , R. of_interval range_ikind (Int64. neg b, b))
312- | _ -> top_of ikind
326+ )
327+ | _ , _ , _ , _ -> top_of ikind
313328 end
314- | _ -> top_of ikind)
329+ | _ -> top_of ikind
330+ )
315331
316332 let shift (shift_op : int_t -> int -> int_t ) (ik : Cil.ikind ) (x : t ) (y : t ) =
317333 handle_bot x y (fun () ->
0 commit comments