Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enums: Take care in refinement that no new elements appear #1675

Merged
merged 1 commit into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions src/cdomain/value/cdomains/int/enumsDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -349,18 +349,28 @@ module Enums : S with type int_t = Z.t = struct
10, QCheck.map pos (BISet.arbitrary ());
] (* S TODO: decide frequencies *)


(* One needs to be exceedingly careful here to not cause new elements to appear that are not originally tracked by the domain *)
(* to avoid breaking the termination guarantee that only constants from the program can appear in exclusion or inclusion sets here *)
(* What is generally safe is shrinking an inclusion set as no new elements appear here. *)
(* What is not safe is growing an exclusion set or switching from an exclusion set to an inclusion set *)

let refine_with_congruence ik a b =
let contains c m x = if Z.equal m Z.zero then Z.equal c x else Z.equal (Z.rem (Z.sub x c) m) Z.zero in
match a, b with
| Inc e, None -> bot_of ik
| Inc e, Some (c, m) -> Inc (BISet.filter (contains c m) e)
| _ -> a

let refine_with_interval ik a b = a (* TODO: refine inclusion (exclusion?) set *)
let refine_with_interval ik a b =
match a, b with
| Inc _, None -> bot_of ik
| Inc e, Some (l, u) -> Inc (BISet.filter (value_in_range (l,u)) e)
| _ -> a

let refine_with_excl_list ik a b =
match b with
| Some (ls, _) -> meet ik a (of_excl_list ik ls) (* TODO: refine with excl range? *)
match a, b with
| Inc _, Some (ls, _) -> meet ik a (of_excl_list ik ls) (* TODO: refine with excl range? *)
| _ -> a

let refine_with_incl_list ik a b =
Expand Down
9 changes: 9 additions & 0 deletions tests/regression/38-int-refinements/07-enums.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// PARAM: --set ana.int.refinement fixpoint --enable ana.int.def_exc --enable ana.int.enums --enable ana.int.interval --set sem.int.signed_overflow assume_none
// NOTIMEOUT: Used to not reach terminate (https://github.com/goblint/analyzer/issues/1671) and (https://github.com/goblint/analyzer/issues/1673)
int main() {
int count = 0;
while (1) {
count++;
count++;
}
}
Loading