Skip to content

Commit 308b471

Browse files
authored
Merge pull request #1727 from goblint/intdomain-no-top
Remove dummy `top` and `is_top` implementations from int domains
2 parents fea1514 + a968622 commit 308b471

File tree

10 files changed

+53
-41
lines changed

10 files changed

+53
-41
lines changed

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

+14-16
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ struct
8181
let name () = "def_exc"
8282

8383

84-
let top_range = R.of_interval range_ikind (-99L, 99L) (* Since there is no top ikind we use a range that includes both ILongLong [-63,63] and IULongLong [0,64]. Only needed for intermediate range computation on longs. Correct range is set by cast. *)
85-
let top () = `Excluded (S.empty (), top_range)
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. *)
85+
let top_overflow () = `Excluded (S.empty (), overflow_range)
8686
let bot () = `Bot
8787
let top_of ik = `Excluded (S.empty (), size ik)
8888
let bot_of ik = bot ()
@@ -117,8 +117,6 @@ struct
117117
let upperb = Exclusion.max_of_range r in
118118
Z.compare i upperb <= 0
119119

120-
let is_top x = x = top ()
121-
122120
let equal_to i = function
123121
| `Bot -> failwith "unsupported: equal_to with bottom"
124122
| `Definite x -> if i = x then `Eq else `Neq
@@ -351,10 +349,10 @@ struct
351349
(* We don't bother with exclusion sets: *)
352350
| `Excluded _, `Definite _
353351
| `Definite _, `Excluded _
354-
| `Excluded _, `Excluded _ -> top ()
352+
| `Excluded _, `Excluded _ -> top_overflow ()
355353
(* The good case: *)
356354
| `Definite x, `Definite y ->
357-
(try `Definite (f x y) with | Division_by_zero -> top ())
355+
(try `Definite (f x y) with | Division_by_zero -> top_overflow ())
358356
| `Bot, `Bot -> `Bot
359357
| _ ->
360358
(* If only one of them is bottom, we raise an exception that eval_rv will catch *)
@@ -367,7 +365,7 @@ struct
367365
norm ik @@
368366
match x,y with
369367
(* If both are exclusion sets, there isn't anything we can do: *)
370-
| `Excluded _, `Excluded _ -> top ()
368+
| `Excluded _, `Excluded _ -> top_overflow ()
371369
(* A definite value should be applied to all members of the exclusion set *)
372370
| `Definite x, `Excluded (s,r) -> def_exc f x s r
373371
(* Same thing here, but we should flip the operator to map it properly *)
@@ -382,11 +380,11 @@ struct
382380
(* The equality check: *)
383381
let eq ik x y = match x,y with
384382
(* Not much to do with two exclusion sets: *)
385-
| `Excluded _, `Excluded _ -> top ()
383+
| `Excluded _, `Excluded _ -> top_of IInt
386384
(* Is x equal to an exclusion set, if it is a member then NO otherwise we
387385
* don't know: *)
388-
| `Definite x, `Excluded (s,r) -> if S.mem x s then of_bool IInt false else top ()
389-
| `Excluded (s,r), `Definite x -> if S.mem x s then of_bool IInt false else top ()
386+
| `Definite x, `Excluded (s,r) -> if S.mem x s then of_bool IInt false else top_of IInt
387+
| `Excluded (s,r), `Definite x -> if S.mem x s then of_bool IInt false else top_of IInt
390388
(* The good case: *)
391389
| `Definite x, `Definite y -> of_bool IInt (x = y)
392390
| `Bot, `Bot -> `Bot
@@ -397,11 +395,11 @@ struct
397395
(* The inequality check: *)
398396
let ne ik x y = match x,y with
399397
(* Not much to do with two exclusion sets: *)
400-
| `Excluded _, `Excluded _ -> top ()
398+
| `Excluded _, `Excluded _ -> top_of IInt
401399
(* Is x unequal to an exclusion set, if it is a member then Yes otherwise we
402400
* don't know: *)
403-
| `Definite x, `Excluded (s,r) -> if S.mem x s then of_bool IInt true else top ()
404-
| `Excluded (s,r), `Definite x -> if S.mem x s then of_bool IInt true else top ()
401+
| `Definite x, `Excluded (s,r) -> if S.mem x s then of_bool IInt true else top_of IInt
402+
| `Excluded (s,r), `Definite x -> if S.mem x s then of_bool IInt true else top_of IInt
405403
(* The good case: *)
406404
| `Definite x, `Definite y -> of_bool IInt (x <> y)
407405
| `Bot, `Bot -> `Bot
@@ -460,12 +458,12 @@ struct
460458
else if Z.equal i Z.one then
461459
of_interval IBool (Z.zero, Z.one)
462460
else
463-
top ()
461+
top_of ik
464462
| `Definite _, `Excluded _
465-
| `Excluded _, `Excluded _ -> top ()
463+
| `Excluded _, `Excluded _ -> top_of ik
466464
(* The good case: *)
467465
| `Definite x, `Definite y ->
468-
(try `Definite (Z.logand x y) with | Division_by_zero -> top ())
466+
(try `Definite (Z.logand x y) with | Division_by_zero -> top_of ik)
469467
| `Bot, `Bot -> `Bot
470468
| _ ->
471469
(* If only one of them is bottom, we raise an exception that eval_rv will catch *)

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

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ module Enums : S with type int_t = Z.t = struct
1919
type int_t = Z.t
2020
let name () = "enums"
2121
let bot () = failwith "bot () not implemented for Enums"
22-
let top () = failwith "top () not implemented for Enums"
2322
let bot_of ik = Inc (BISet.empty ())
2423
let top_bool = Inc (BISet.of_list [Z.zero; Z.one])
2524
let top_of ik =

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

-2
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ module IntDomTupleImpl = struct
114114
| _ -> true
115115

116116
(* f0: constructors *)
117-
let top () = create { fi = fun (type a) (module I:SOverflow with type t = a) -> I.top } ()
118117
let bot () = create { fi = fun (type a) (module I:SOverflow with type t = a) -> I.bot } ()
119118
let top_of = create { fi = fun (type a) (module I:SOverflow with type t = a) -> I.top_of }
120119
let bot_of = create { fi = fun (type a) (module I:SOverflow with type t = a) -> I.bot_of }
@@ -206,7 +205,6 @@ module IntDomTupleImpl = struct
206205

207206
(* exists/for_all *)
208207
let is_bot = exists % mapp { fp = fun (type a) (module I:SOverflow with type t = a) -> I.is_bot }
209-
let is_top = for_all % mapp { fp = fun (type a) (module I:SOverflow with type t = a) -> I.is_top }
210208
let is_top_of ik = for_all % mapp { fp = fun (type a) (module I:SOverflow with type t = a) -> I.is_top_of ik }
211209
let is_excl_list = exists % mapp { fp = fun (type a) (module I:SOverflow with type t = a) -> I.is_excl_list }
212210

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

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ struct
99

1010
let range ik = BatTuple.Tuple2.mapn Ints_t.of_bigint (Size.range ik)
1111

12-
let top () = failwith @@ "top () not implemented for " ^ (name ())
1312
let top_of ik = Some (range ik)
1413
let bot () = None
1514
let bot_of ik = bot () (* TODO: improve *)

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

-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ struct
3131

3232
let range ik = BatTuple.Tuple2.mapn Ints_t.of_bigint (Size.range ik)
3333

34-
let top () = failwith @@ "top () not implemented for " ^ (name ())
35-
3634
let top_of ik = [range ik]
3735

3836
let bot () = []

src/cdomain/value/cdomains/intDomain.mli

+4-4
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,8 @@ end
170170
(* Shared signature of IntDomain implementations and the lifted IntDomains *)
171171
module type B =
172172
sig
173-
include Lattice.S
173+
include Lattice.PO
174+
include Lattice.Bot with type t := t
174175
type int_t
175176
(** {b Accessing values of the ADT} *)
176177

@@ -215,6 +216,7 @@ end
215216
module type IkindUnawareS =
216217
sig
217218
include B
219+
include Lattice.Top with type t := t
218220
include Arith with type t:= t
219221
val starting : ?suppress_ovwarn:bool -> Cil.ikind -> int_t -> t
220222
val ending : ?suppress_ovwarn:bool -> Cil.ikind -> int_t -> t
@@ -316,6 +318,7 @@ module SOverflowUnlifter (D : SOverflow) : S with type int_t = D.int_t and type
316318
module type Y =
317319
sig
318320
include B
321+
include Lattice.Top with type t := t
319322
include Arith with type t:=t
320323

321324
val of_int: Cil.ikind -> int_t -> t
@@ -439,9 +442,6 @@ module Flat (Base: IkindUnawareS): IkindUnawareS with type t = [ `Bot | `Lifted
439442
module Lift (Base: IkindUnawareS): IkindUnawareS with type t = [ `Bot | `Lifted of Base.t | `Top ] and type int_t = Base.int_t
440443
(** Just like {!Value.Flat} except the order is preserved. *)
441444

442-
module Reverse (Base: IkindUnawareS): IkindUnawareS with type t = Base.t and type int_t = Base.int_t
443-
(** Reverses bot, top, leq, join, meet *)
444-
445445
(* module Interval : S *)
446446
(** Interval domain with int64-s --- use with caution! *)
447447

src/cdomain/value/cdomains/intDomain0.ml

+6-10
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,8 @@ end
161161
(* Shared functions between S and Z *)
162162
module type B =
163163
sig
164-
include Lattice.S
164+
include Lattice.PO
165+
include Lattice.Bot with type t := t
165166
type int_t
166167
val bot_of: Cil.ikind -> t
167168
val top_of: Cil.ikind -> t
@@ -185,6 +186,7 @@ end
185186
module type IkindUnawareS =
186187
sig
187188
include B
189+
include Lattice.Top with type t := t
188190
include Arith with type t := t
189191
val starting : ?suppress_ovwarn:bool -> Cil.ikind -> int_t -> t
190192
val ending : ?suppress_ovwarn:bool -> Cil.ikind -> int_t -> t
@@ -277,8 +279,8 @@ end
277279

278280
module type Y =
279281
sig
280-
(* include B *)
281282
include B
283+
include Lattice.Top with type t := t
282284
include Arith with type t:= t
283285
val of_int: Cil.ikind -> int_t -> t
284286
val of_bool: Cil.ikind -> bool -> t
@@ -319,7 +321,7 @@ struct
319321
let is_bot x = I.is_bot x.v
320322
let top_of ikind = { v = I.top_of ikind; ikind}
321323
let top () = failwith "top () is not implemented for IntDomLifter."
322-
let is_top x = I.is_top x.v
324+
let is_top _ = failwith "is_top is not implemented for IntDomLifter."
323325

324326
(* Leq does not check for ikind, because it is used in invariant with arguments of different type.
325327
TODO: check ikinds here and fix invariant to work with right ikinds *)
@@ -417,6 +419,7 @@ module IntDomWithDefaultIkind (I: Y) (Ik: Ikind) : Y with type t = I.t and type
417419
struct
418420
include I
419421
let top () = I.top_of (Ik.ikind ())
422+
let is_top x = I.is_top_of (Ik.ikind ()) x
420423
let bot () = I.bot_of (Ik.ikind ())
421424
end
422425

@@ -520,7 +523,6 @@ module Std (B: sig
520523
include Printable.StdLeaf
521524
let name = B.name (* overwrite the one from Printable.Std *)
522525
open B
523-
let is_top x = failwith "is_top not implemented for IntDomain.Std"
524526
let is_bot x = B.equal x (bot_of Cil.IInt) (* Here we assume that the representation of bottom is independent of the ikind
525527
This may be true for intdomain implementations, but not e.g. for IntDomLifter. *)
526528
let is_top_of ik x = B.equal x (top_of ik)
@@ -907,12 +909,6 @@ end
907909
module Flattened = Flat (Integers (IntOps.Int64Ops))
908910
module Lifted = Lift (Integers (IntOps.Int64Ops))
909911

910-
module Reverse (Base: IkindUnawareS) =
911-
struct
912-
include Base
913-
include (Lattice.Reverse (Base) : Lattice.S with type t := Base.t)
914-
end
915-
916912
module SOverflowLifter (D : S) : SOverflow with type int_t = D.int_t and type t = D.t = struct
917913

918914
include D

src/domain/lattice.ml

+15-3
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,28 @@ sig
2727
val pretty_diff: unit -> (t * t) -> Pretty.doc
2828
end
2929

30-
(* complete lattice *)
31-
module type S =
30+
module type Bot =
3231
sig
33-
include PO
32+
type t
3433
val bot: unit -> t
3534
val is_bot: t -> bool
35+
end
36+
37+
module type Top =
38+
sig
39+
type t
3640
val top: unit -> t
3741
val is_top: t -> bool
3842
end
3943

44+
(* complete lattice *)
45+
module type S =
46+
sig
47+
include PO
48+
include Bot with type t := t
49+
include Top with type t := t
50+
end
51+
4052
exception TopValue
4153
(** Exception raised by a topless lattice in place of a top value.
4254
Surrounding lattice functors may handle this on their own. *)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#include <goblint.h>
2+
#include <limits.h>
3+
4+
// There are no 128bit integer literals...
5+
__int128 int128max = ((__int128) LLONG_MAX) << 64 | ULLONG_MAX;
6+
7+
int main() {
8+
__int128 x, y, z;
9+
z = x + y;
10+
__goblint_check(z < int128max); // UNKNOWN!
11+
return 0;
12+
}

tests/unit/cdomains/intDomainTest.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -555,8 +555,8 @@ struct
555555
(Printf.sprintf "test_shift_right_ik_%s" (CilType.Ikind.show ik)) Int.shift_right I.shift_right :: acc
556556
) [] ik_lst |> QCheck_ounit.to_ounit2_test_list
557557

558-
let bot = `B (I.bot ())
559-
let top = `B (I.top ())
558+
let bot = `B (I.bot_of ik)
559+
let top = `B (I.top_of ik)
560560

561561
let isSigned = GoblintCil.Cil.isSigned
562562

0 commit comments

Comments
 (0)