You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
|Somex2, _ -> Invariant.of_exp Cil.(BinOp (Le, e, kintegerCilint ik x2, intType))
624
+
|None, _ -> Invariant.none
625
+
in
626
+
Invariant.(i1 && i2)
627
+
628
+
letof_intervaleik (x1, x2) =
629
+
of_interval_opt e ik (Some x1, Some x2)
630
+
631
+
letof_excl_listeikns=
632
+
List.fold_left (funax ->
633
+
let i =Invariant.of_exp Cil.(BinOp (Ne, e, kintegerCilint ik x, intType)) in
634
+
Invariant.(a && i)
635
+
) (Invariant.top ()) ns
636
+
end
637
+
585
638
moduleIntervalFunctor (Ints_t : IntOps.IntOps): SOverflow with type int_t = Ints_t.t and type t = (Ints_t.t * Ints_t.t) option=
586
639
struct
587
640
letname()="intervals"
@@ -915,21 +968,10 @@ struct
915
968
elseifInts_t.compare y2 x1 <=0then of_bool ik false
916
969
else top_bool
917
970
918
-
letinvariant_ikindeikx=
919
-
match x with
920
-
|Some (x1, x2) whenInts_t.compare x1 x2 =0 ->
921
-
if get_bool "witness.invariant.exact"then
922
-
let x1 =Ints_t.to_bigint x1 in
923
-
Invariant.of_exp Cil.(BinOp (Eq, e, kintegerCilint ik x1, intType))
924
-
else
925
-
Invariant.top ()
971
+
letinvariant_ikindeik=function
926
972
|Some (x1, x2) ->
927
-
let (min_ik, max_ik) = range ik in
928
-
let (x1', x2') =BatTuple.Tuple2.mapn (Ints_t.to_bigint) (x1, x2) in
929
-
let inexact_type_bounds = get_bool "witness.invariant.inexact-type-bounds"in
930
-
let i1 =if inexact_type_bounds ||Ints_t.compare min_ik x1 <>0thenInvariant.of_exp Cil.(BinOp (Le, kintegerCilint ik x1', e, intType)) elseInvariant.none in
931
-
let i2 =if inexact_type_bounds ||Ints_t.compare x2 max_ik <>0thenInvariant.of_exp Cil.(BinOp (Le, e, kintegerCilint ik x2', intType)) elseInvariant.none in
932
-
Invariant.(i1 && i2)
973
+
let (x1', x2') =BatTuple.Tuple2.mapn Ints_t.to_bigint (x1, x2) in
974
+
IntInvariant.of_interval e ik (x1', x2')
933
975
|None -> Invariant.none
934
976
935
977
letarbitraryik=
@@ -2297,25 +2339,14 @@ struct
2297
2339
letinvariant_ikindeik (x:t) =
2298
2340
match x with
2299
2341
|`Definitex ->
2300
-
if get_bool "witness.invariant.exact"then
2301
-
Invariant.of_exp Cil.(BinOp (Eq, e, kintegerCilint ik x, intType))
2302
-
else
2303
-
Invariant.top ()
2342
+
IntInvariant.of_int e ik x
2304
2343
|`Excluded (s, r) ->
2305
2344
(* Emit range invariant if tighter than ikind bounds.
2306
2345
This can be more precise than interval, which has been widened. *)
2307
2346
let (rmin, rmax) = (Exclusion.min_of_range r, Exclusion.max_of_range r) in
let inexact_type_bounds = get_bool "witness.invariant.inexact-type-bounds"in
2313
-
let imin =if inexact_type_bounds ||Z.compare ikmin rmin <>0thenInvariant.of_exp Cil.(BinOp (Le, kintegerCilint ik rmin, e, intType)) elseInvariant.none in
2314
-
let imax =if inexact_type_bounds ||Z.compare rmax ikmax <>0thenInvariant.of_exp Cil.(BinOp (Le, e, kintegerCilint ik rmax, intType)) elseInvariant.none in
2315
-
S.fold (funxa ->
2316
-
let i =Invariant.of_exp Cil.(BinOp (Ne, e, kintegerCilint ik x, intType)) in
2317
-
Invariant.(a && i)
2318
-
) s Invariant.(imin && imax)
2347
+
let ri =IntInvariant.of_interval e ik (rmin, rmax) in
2348
+
let si =IntInvariant.of_excl_list e ik (S.elements s) in
2349
+
Invariant.(ri && si)
2319
2350
|`Bot -> Invariant.none
2320
2351
2321
2352
letarbitraryik=
@@ -2731,32 +2762,16 @@ module Enums : S with type int_t = Z.t = struct
2731
2762
letneikxy= c_lognot ik (eq ik x y)
2732
2763
2733
2764
letinvariant_ikindeikx=
2734
-
let inexact_type_bounds = get_bool "witness.invariant.inexact-type-bounds"in
2735
2765
match x with
2736
-
|Incpswhennot inexact_type_bounds && ik =IBool&& is_top_of ik x ->
let imin =if inexact_type_bounds ||Z.compare ikmin rmin <>0thenInvariant.of_exp Cil.(BinOp (Le, kintegerCilint ik rmin, e, intType)) elseInvariant.none in
2755
-
let imax =if inexact_type_bounds ||Z.compare rmax ikmax <>0thenInvariant.of_exp Cil.(BinOp (Le, e, kintegerCilint ik rmax, intType)) elseInvariant.none in
2756
-
BISet.fold (funxa ->
2757
-
let i =Invariant.of_exp Cil.(BinOp (Ne, e, kintegerCilint ik x, intType)) in
2758
-
Invariant.(a && i)
2759
-
) ns Invariant.(imin && imax)
2772
+
let ri =IntInvariant.of_interval e ik (rmin, rmax) in
2773
+
let nsi =IntInvariant.of_excl_list e ik (BISet.elements ns) in
2774
+
Invariant.(ri && nsi)
2760
2775
2761
2776
2762
2777
letarbitraryik=
@@ -2779,7 +2794,7 @@ module Enums : S with type int_t = Z.t = struct
2779
2794
|Ince, Some (c, m) -> Inc (BISet.filter (contains c m) e)
2780
2795
|_ -> a
2781
2796
2782
-
letrefine_with_intervalikab= a
2797
+
letrefine_with_intervalikab= a(* TODO: refine inclusion (exclusion?) set *)
2783
2798
2784
2799
letrefine_with_excl_listikab=
2785
2800
match b with
@@ -3243,10 +3258,7 @@ struct
3243
3258
match x with
3244
3259
|xwhen is_top x -> Invariant.top ()
3245
3260
|Some (c, m) when m =:Z.zero ->
3246
-
if get_bool "witness.invariant.exact"then
3247
-
Invariant.of_exp Cil.(BinOp (Eq, e, Cil.kintegerCilint ik c, intType))
3248
-
else
3249
-
Invariant.top ()
3261
+
IntInvariant.of_int e ik c
3250
3262
|Some (c, m) ->
3251
3263
letopenCilin
3252
3264
let (c, m) =BatTuple.Tuple2.mapn (funa -> kintegerCilint ik a) (c, m) in
(* TODO: do refinement before to ensure incl_list being more precise than intervals, etc (https://github.com/goblint/analyzer/pull/1517#discussion_r1693998515), requires refine functions to actually refine that *)
3794
+
letsimplify_intfallback=
3795
+
match to_int x with
3796
+
|Somev ->
3797
+
(* If definite, output single equality instead of every subdomain repeating same equality (or something less precise). *)
3798
+
IntInvariant.of_int e ik v
3799
+
|None ->
3800
+
fallback ()
3801
+
in
3802
+
letsimplify_all()=
3803
+
match to_incl_list x with
3804
+
|Someps ->
3805
+
(* If inclusion set, output disjunction of equalities because it subsumes interval(s), exclusion set and congruence. *)
3806
+
IntInvariant.of_incl_list e ik ps
3807
+
|None ->
3808
+
(* Get interval bounds from all domains (intervals and exclusion set ranges). *)
3809
+
let min = minimal x in
3810
+
let max = maximal x in
3811
+
let ns =Option.map fst (to_excl_list x) |?[]in(* Ignore exclusion set bit range, known via interval bounds already. *)
3812
+
(* "Refine" out-of-bounds exclusions for simpler output. *)
3813
+
let ns =Option.map_default (funmin -> List.filter (Z.leq min) ns) ns min in
3814
+
let ns =Option.map_default (funmax -> List.filter (Z.geq max) ns) ns max in
3815
+
Invariant.(
3816
+
IntInvariant.of_interval_opt e ik (min, max) &&(* Output best interval bounds once instead of multiple subdomains repeating them (or less precise ones). *)
3817
+
IntInvariant.of_excl_list e ik ns &&
3818
+
Option.map_default (I4.invariant_ikind e ik) Invariant.none x_cong &&(* Output congruence as is. *)
3819
+
Option.map_default (I5.invariant_ikind e ik) Invariant.none x_intset (* Output interval sets as is. *)
3820
+
)
3821
+
in
3822
+
letsimplify_none()=
3823
+
let is = to_list (mapp { fp =fun (typea) (module I:SOverflow with type t = a) -> I.invariant_ikind e ik } x) in
Copy file name to clipboardExpand all lines: src/config/options.schema.json
+14
Original file line number
Diff line number
Diff line change
@@ -807,6 +807,20 @@
807
807
"type": "string",
808
808
"enum": ["once", "fixpoint"],
809
809
"default": "once"
810
+
},
811
+
"int": {
812
+
"title": "ana.base.invariant.int",
813
+
"type": "object",
814
+
"properties": {
815
+
"simplify": {
816
+
"title": "ana.base.invariant.int.simplify",
817
+
"description": "How much to simplify int domain invariants. Value \"int\" only simplifies definite integers. Without int domain refinement \"all\" might not be maximally precise.",
0 commit comments