Skip to content

Commit 3d7c7b7

Browse files
committed
Simplify exclusion bit range module
1 parent 77d0264 commit 3d7c7b7

File tree

6 files changed

+53
-34
lines changed

6 files changed

+53
-34
lines changed

src/cdomain/value/cdomains/int/defExcDomain.ml

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ end
1111
(* The module [Exclusion] constains common functionality about handling of exclusion sets between [DefExc] and [Enums] *)
1212
module Exclusion =
1313
struct
14-
module R = Interval32
14+
module R = IntervalArith (IntOps.Int64Ops)
1515
(* We use these types for the functions in this module to make the intended meaning more explicit *)
16-
type t = Exc of BISet.t * Interval32.t
16+
type t = Exc of BISet.t * R.t
1717
type inc = Inc of BISet.t [@@unboxed]
18-
let max_of_range r = Size.max_from_bit_range (Option.get (R.maximal r))
19-
let min_of_range r = Size.min_from_bit_range (Option.get (R.minimal r))
18+
let max_of_range r = Size.max_from_bit_range (R.maximal r)
19+
let min_of_range r = Size.min_from_bit_range (R.minimal r)
2020
let cardinality_of_range r = Z.succ (Z.add (Z.neg (min_of_range r)) (max_of_range r))
2121

2222
let cardinality_BISet s =
@@ -65,11 +65,11 @@ end
6565
module DefExc : S with type int_t = Z.t = (* definite or set of excluded values *)
6666
struct
6767
module S = BISet
68-
module R = Interval32 (* range for exclusion *)
68+
module R = Exclusion.R (* range for exclusion *)
6969

7070
(* Ikind used for intervals representing the domain *)
7171
let range_ikind = Cil.IInt
72-
let size t = R.of_interval range_ikind (let a,b = Size.bits_i64 t in Int64.neg a,b)
72+
let size t = let a,b = Size.bits_i64 t in Int64.neg a,b
7373

7474

7575
type t = [
@@ -81,7 +81,7 @@ struct
8181
let name () = "def_exc"
8282

8383

84-
let overflow_range = R.of_interval range_ikind (-999L, 999L) (* Since there is no top ikind we use a range that includes both IInt128 [-127,127] and IUInt128 [0,128]. Only needed for intermediate range computation on longs. Correct range is set by cast. *)
84+
let overflow_range = (-999L, 999L) (* Since there is no top ikind we use a range that includes both IInt128 [-127,127] and IUInt128 [0,128]. Only needed for intermediate range computation on longs. Correct range is set by cast. *)
8585
let top_overflow () = `Excluded (S.empty (), overflow_range)
8686
let bot () = `Bot
8787
let top_of ik = `Excluded (S.empty (), size ik)
@@ -226,14 +226,14 @@ struct
226226
(* Unless one of them is zero, we can exclude it: *)
227227
else
228228
let a,b = Size.min_range_sign_agnostic x, Size.min_range_sign_agnostic y in
229-
let r = R.join (R.of_interval range_ikind a) (R.of_interval range_ikind b) in
229+
let r = R.join a b in
230230
`Excluded ((if Z.equal x Z.zero || Z.equal y Z.zero then S.empty () else S.singleton Z.zero), r)
231231
(* A known value and an exclusion set... the definite value should no
232232
* longer be excluded: *)
233233
| `Excluded (s,r), `Definite x
234234
| `Definite x, `Excluded (s,r) ->
235235
if not (in_range r x) then
236-
let a = R.of_interval range_ikind (Size.min_range_sign_agnostic x) in
236+
let a = Size.min_range_sign_agnostic x in
237237
`Excluded (S.remove x s, R.join a r)
238238
else
239239
`Excluded (S.remove x s, r)
@@ -266,9 +266,11 @@ struct
266266
(* The greatest lower bound of two exclusion sets is their union, this is
267267
* just DeMorgans Law *)
268268
| `Excluded (x,r1), `Excluded (y,r2) ->
269-
let r' = R.meet r1 r2 in
270-
let s' = S.union x y |> S.filter (in_range r') in
271-
`Excluded (s', r')
269+
match R.meet r1 r2 with
270+
| None -> `Bot
271+
| Some r' ->
272+
let s' = S.union x y |> S.filter (in_range r') in
273+
`Excluded (s', r')
272274

273275
let narrow ik x y = x
274276

@@ -286,14 +288,14 @@ struct
286288
| `Definite x -> Some (IntOps.BigIntOps.to_bool x)
287289
| `Excluded (s,r) when S.mem Z.zero s -> Some true
288290
| _ -> None
289-
let top_bool = `Excluded (S.empty (), R.of_interval range_ikind (0L, 1L))
291+
let top_bool = `Excluded (S.empty (), (0L, 1L))
290292

291293
let of_interval ik (x,y) =
292294
if Z.compare x y = 0 then
293295
of_int ik x
294296
else
295297
let a, b = Size.min_range_sign_agnostic x, Size.min_range_sign_agnostic y in
296-
let r = R.join (R.of_interval range_ikind a) (R.of_interval range_ikind b) in
298+
let r = R.join a b in
297299
let ex = if Z.gt x Z.zero || Z.lt y Z.zero then S.singleton Z.zero else S.empty () in
298300
norm ik @@ (`Excluded (ex, r))
299301

@@ -323,7 +325,7 @@ struct
323325
let is_excl_list l = match l with `Excluded _ -> true | _ -> false
324326
let to_excl_list (x:t) = match x with
325327
| `Definite _ -> None
326-
| `Excluded (s,r) -> Some (S.elements s, (Option.get (R.minimal r), Option.get (R.maximal r)))
328+
| `Excluded (s,r) -> Some (S.elements s, r)
327329
| `Bot -> None
328330

329331
let to_incl_list x = match x with

src/cdomain/value/cdomains/int/enumsDomain.ml

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ open GoblintCil
66

77
(* Inclusion/Exclusion sets. Go to top on arithmetic operations (except for some easy cases, e.g. multiplication with 0). Joins on widen, i.e. precise integers as long as not derived from arithmetic expressions. *)
88
module Enums : S with type int_t = Z.t = struct
9-
module R = Interval32 (* range for exclusion *)
9+
module R = Exclusion.R (* range for exclusion *)
1010

1111
let range_ikind = Cil.IInt
12-
let size t = R.of_interval range_ikind (let a,b = Size.bits_i64 t in Int64.neg a,b)
12+
let size t = let a,b = Size.bits_i64 t in Int64.neg a,b
1313

1414
type t =
1515
| Inc of BISet.t (* Inclusion set. *)
@@ -18,8 +18,8 @@ module Enums : S with type int_t = Z.t = struct
1818

1919
type int_t = Z.t
2020
let name () = "enums"
21-
let bot () = failwith "bot () not implemented for Enums"
22-
let bot_of ik = Inc (BISet.empty ())
21+
let bot () = Inc (BISet.empty ())
22+
let bot_of ik = bot ()
2323
let top_bool = Inc (BISet.of_list [Z.zero; Z.one])
2424
let top_of ik =
2525
match ik with
@@ -113,7 +113,7 @@ module Enums : S with type int_t = Z.t = struct
113113
of_int ik x
114114
else
115115
let a, b = Size.min_range_sign_agnostic x, Size.min_range_sign_agnostic y in
116-
let r = R.join (R.of_interval range_ikind a) (R.of_interval range_ikind b) in
116+
let r = R.join a b in
117117
let ex = if Z.gt x Z.zero || Z.lt y Z.zero then BISet.singleton Z.zero else BISet.empty () in
118118
norm ik @@ (Exc (ex, r))
119119

@@ -126,22 +126,25 @@ module Enums : S with type int_t = Z.t = struct
126126
let r = if BISet.is_empty y
127127
then r
128128
else
129-
let (min_el_range, max_el_range) = Batteries.Tuple2.mapn (fun x -> R.of_interval range_ikind (Size.min_range_sign_agnostic x)) (BISet.min_elt y, BISet.max_elt y) in
129+
let (min_el_range, max_el_range) = Batteries.Tuple2.mapn Size.min_range_sign_agnostic (BISet.min_elt y, BISet.max_elt y) in
130130
let range = R.join min_el_range max_el_range in
131131
R.join r range
132132
in
133133
Exc (BISet.diff x y, r)
134134

135-
let meet _ x y =
135+
let meet ik x y =
136136
match x, y with
137137
| Inc x, Inc y -> Inc (BISet.inter x y)
138138
| Exc (x,r1), Exc (y,r2) ->
139-
let r = R.meet r1 r2 in
140-
let r_min, r_max = Exclusion.min_of_range r, Exclusion.max_of_range r in
141-
let filter_by_range = BISet.filter (value_in_range (r_min, r_max)) in
142-
(* We remove those elements from the exclusion set that do not fit in the range anyway *)
143-
let excl = BISet.union (filter_by_range x) (filter_by_range y) in
144-
Exc (excl, r)
139+
begin match R.meet r1 r2 with
140+
| None -> bot ()
141+
| Some r ->
142+
let r_min, r_max = Exclusion.min_of_range r, Exclusion.max_of_range r in
143+
let filter_by_range = BISet.filter (value_in_range (r_min, r_max)) in
144+
(* We remove those elements from the exclusion set that do not fit in the range anyway *)
145+
let excl = BISet.union (filter_by_range x) (filter_by_range y) in
146+
Exc (excl, r)
147+
end
145148
| Inc x, Exc (y,r)
146149
| Exc (y,r), Inc x -> Inc (BISet.diff x y)
147150

@@ -244,7 +247,7 @@ module Enums : S with type int_t = Z.t = struct
244247
| _ -> None
245248
let to_int = function Inc x when BISet.is_singleton x -> Some (BISet.choose x) | _ -> None
246249

247-
let to_excl_list = function Exc (x,r) when not (BISet.is_empty x) -> Some (BISet.elements x, (Option.get (R.minimal r), Option.get (R.maximal r))) | _ -> None
250+
let to_excl_list = function Exc (x,r) when not (BISet.is_empty x) -> Some (BISet.elements x, r) | _ -> None
248251
let of_excl_list ik xs =
249252
let min_ik, max_ik = Size.range ik in
250253
let exc = BISet.of_list @@ List.filter (value_in_range (min_ik, max_ik)) xs in

src/cdomain/value/cdomains/int/intervalDomain.ml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ struct
123123
let ending ik n =
124124
norm ik @@ Some (fst (range ik), n)
125125

126-
(* TODO: change signature of maximal, minimal to return big_int*)
127126
let maximal = function None -> None | Some (x,y) -> Some y
128127
let minimal = function None -> None | Some (x,y) -> Some x
129128

@@ -445,4 +444,3 @@ struct
445444
end
446445

447446
module Interval = IntervalFunctor (IntOps.BigIntOps)
448-
module Interval32 = IntDomWithDefaultIkind (IntDomLifter (SOverflowUnlifter (IntervalFunctor (IntOps.Int64Ops)))) (IntIkind)

src/cdomain/value/cdomains/intDomain0.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,11 @@ end
346346

347347
(* Textbook interval arithmetic, without any overflow handling etc. *)
348348
module IntervalArith (Ints_t : IntOps.IntOps) = struct
349+
type t = Ints_t.t * Ints_t.t [@@deriving eq, ord, hash]
350+
351+
(* TODO: use this for Interval and IntervalSet *)
352+
let show (x,y) = "["^Ints_t.to_string x^","^Ints_t.to_string y^"]"
353+
349354
let min4 a b c d = Ints_t.min (Ints_t.min a b) (Ints_t.min c d)
350355
let max4 a b c d = Ints_t.max (Ints_t.max a b) (Ints_t.max c d)
351356

@@ -381,6 +386,20 @@ module IntervalArith (Ints_t : IntOps.IntOps) = struct
381386
let zero = (Ints_t.zero, Ints_t.zero)
382387
let top_bool = (Ints_t.zero, Ints_t.one)
383388

389+
(* TODO: use these for Interval and IntervalSet *)
390+
let maximal = snd
391+
let minimal = fst
392+
393+
(* TODO: use these for Interval and IntervalSet *)
394+
let leq (x1,x2) (y1,y2) = Ints_t.compare x1 y1 >= 0 && Ints_t.compare x2 y2 <= 0
395+
let join (x1,x2) (y1,y2) = (Ints_t.min x1 y1, Ints_t.max x2 y2)
396+
let meet (x1,x2) (y1,y2) =
397+
let (r1, r2) as r = (Ints_t.max x1 y1, Ints_t.min x2 y2) in
398+
if Ints_t.compare r1 r2 > 0 then
399+
None
400+
else
401+
Some r
402+
384403
let to_int (x1, x2) =
385404
if Ints_t.equal x1 x2 then Some x1 else None
386405

src/cdomain/value/cdomains/intDomain_intf.ml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,6 @@ sig
440440

441441
module IntervalSetFunctor(Ints_t : IntOps.IntOps): SOverflow with type int_t = Ints_t.t and type t = (Ints_t.t * Ints_t.t) list
442442

443-
module Interval32 :Y with (* type t = (IntOps.Int64Ops.t * IntOps.Int64Ops.t) option and *) type int_t = IntOps.Int64Ops.t
444-
445443
module Interval : SOverflow with type int_t = Z.t
446444

447445
module Bitfield : SOverflow with type int_t = Z.t

tests/unit/maindomaintest.ml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ let intDomains: (module IntDomainProperties.S2) list = [
4848
(module IntDomain.SOverflowUnlifter(IntDomain.IntervalSet));
4949
(module IntDomain.SOverflowUnlifter(IntDomain.Bitfield));
5050
(* (module IntDomain.Flattened); *)
51-
(* (module IntDomain.Interval32); *)
5251
(* (module IntDomain.Booleans); *)
5352
(* (module IntDomain.IntDomTuple); *)
5453
]

0 commit comments

Comments
 (0)