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

Optimize and refactor "Hoare" domains #809

Merged
merged 81 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
768b4fb
Add tests to show buggy Hoare domain usage
sim642 Jul 29, 2022
ec013be
Attempt to reimplement AddressDomain using projective hoare domain
sim642 Jul 29, 2022
7ad1c08
Attempt to reimplement AddressDomain using pairwise hoare domain
sim642 Jul 29, 2022
bda314f
Fix projective AddressDomain by wrapping pairwise
sim642 Jul 29, 2022
1925e6c
Use more precise AddressDomain projection
sim642 Jul 29, 2022
1896076
Add example for old hash-based AddressDomain projection
sim642 Jul 29, 2022
82fb030
Deprecate HoareDomain.HoarePO
sim642 Aug 1, 2022
61690ed
Add joined set abstraction
sim642 Aug 1, 2022
ca0f3d8
Attempt to use Hoare domain for AddressDomain buckets
sim642 Aug 1, 2022
a0555e7
Fix HoareDomain.Pairwise narrow
sim642 Aug 1, 2022
c5f6698
Fix ValueDomain.widen calling AddressDomain.widen incorrectly
sim642 Aug 1, 2022
74fafef
Revert to projective AddressDomain
sim642 Aug 1, 2022
58dd22a
Use HoareDomain.Pairwise for PathSensitive2
sim642 Aug 1, 2022
ff03d1c
Fix Lval.Offset joinability transitivity
sim642 Aug 1, 2022
288c1ea
Add asserts about s1_match cardinality in HoareDomain.Pairwise
sim642 Aug 1, 2022
9f9ccbd
Remove is_element from HoareDomains
sim642 Aug 1, 2022
7438b26
Optimize and refactor HoareDomain.Projective
sim642 Aug 1, 2022
cd50cd9
Optimize and refactor HoareDomain.Pairwise
sim642 Aug 1, 2022
e2b3048
Replace module E with type elt in HoareDomain.NewS
sim642 Aug 1, 2022
14cfb4d
Rename should_join -> cong in HoareDomain
sim642 Aug 1, 2022
fd93942
Make HoareDomain.Pairwise asserts exact
sim642 Aug 1, 2022
6bc127e
Update LvalTest
sim642 Aug 2, 2022
da9c786
Extract SensitiveDomains
sim642 Aug 2, 2022
41e39fb
Move HoareDomain.Joined -> SetDomain.Joined
sim642 Aug 2, 2022
1113247
Remove SensitiveDomain.NewS
sim642 Aug 2, 2022
77792bd
Rename SensitiveDomain.Equivalence -> Congruence
sim642 Aug 2, 2022
1e006d6
Add SensitiveDomain.Combined
sim642 Aug 2, 2022
b792000
Weaken SensitiveDomain E argument signatures
sim642 Aug 2, 2022
6f88615
Fix MapDomainTest
sim642 Aug 2, 2022
fed13ae
Rename Q -> C in Sensitive.Pairwise
sim642 Aug 2, 2022
868519f
Implement missing SetDomain.Joined operations
sim642 Aug 2, 2022
3db120e
Handle Lattice.BotValue in SensitiveDomain
sim642 Aug 2, 2022
d77e476
Make SensitiveDomain.Congruence over elt not t in Combined
sim642 Aug 2, 2022
d012f03
Clean up AddressDomain construction
sim642 Aug 2, 2022
8d6b8cf
Clean up PathSensitive2 construction
sim642 Aug 2, 2022
fdcb8c4
Add assert to 00-sanity/34-hoare-over-addrs
sim642 Aug 3, 2022
32f8567
Merge branch 'hoare-use-bugs' into hoaredomain-new
sim642 Aug 3, 2022
51c8c01
Expand descriptions of hoare-over tests
sim642 Aug 3, 2022
5f4d3e1
Merge branch 'master' into hoaredomain-new
sim642 Aug 3, 2022
5625a63
Switch AddressDomain back to Joined for StrPtr compatibility
sim642 Aug 3, 2022
e3bbd31
Implement Map versions of SensitiveDomain for WitnessConstraints
sim642 Aug 4, 2022
ae50c20
Use PairwiseMap for PathSensitive.Sync
sim642 Aug 4, 2022
d04cd22
Add physical equality short-circuiting to AddressDomain
sim642 Aug 5, 2022
b261e20
Add value output to PairwiseMap
sim642 Aug 5, 2022
bc1527f
Use normal sets for WitnessConstraints ranges
sim642 Aug 5, 2022
24a2fd1
Remove commented out sensitive map code
sim642 Aug 5, 2022
421cf57
Use MapDomain.S for PairwiseMap
sim642 Aug 5, 2022
13ec33e
Add Set suffix to SensitiveDomain sets
sim642 Aug 5, 2022
e39c3fc
Reuse Set and Map printing for SensitiveDomain
sim642 Aug 5, 2022
8a7b601
Implement pretty_diff for SensitiveDomains
sim642 Aug 5, 2022
9ded167
Remove Node and Edge modules from WitnessConstraints
sim642 Aug 5, 2022
47d2bec
Merge branch 'hoaredomain-new-map' into hoaredomain-new
sim642 Aug 5, 2022
7e109cc
Deprecate HoareDomain.MapBot and SetDomain.SensitiveConf
sim642 Aug 5, 2022
4782ccd
Document sensitive domains and related
sim642 Aug 5, 2022
3c35b20
Debug PathSensitive3 sync Not_found crash
sim642 Aug 8, 2022
e5799bc
Work around old LibraryFunctions spawning even with sem.unknown_funct…
sim642 Aug 8, 2022
dd0c0fe
Fix GraphML witnesses with threadspawn
sim642 Aug 8, 2022
1afc8f3
Add witness lifter fixpoint not reached test from sv-benchmarks
sim642 Aug 8, 2022
cde436f
Fix fixpoint not reached error in sv-benchmarks
sim642 Aug 8, 2022
5cb2778
Merge branch 'master' into hoaredomain-new
sim642 Aug 10, 2022
4d4c045
Revert "Fix Lval.Offset joinability transitivity"
sim642 Aug 11, 2022
881ad37
Remove index 0 and first field handling attempt from AddressDomain bu…
sim642 Aug 11, 2022
224a4b6
Remove PairwiseSet from AddressDomain
sim642 Aug 11, 2022
bd0bc27
Remove unused trace_enabled from MapDomain.PMap
sim642 Aug 11, 2022
a0a375a
Revert "Update LvalTest"
sim642 Aug 11, 2022
8d78694
Merge branch 'hoaredomain-new-ad-proj' into hoaredomain-new
sim642 Aug 11, 2022
c19a345
Document Lval special cases not used by AddressDomain splitting any more
sim642 Aug 11, 2022
4e2057e
Rename SensitiveDomain -> DisjointDomain
sim642 Aug 11, 2022
3a2a226
Add witness lifter path sensitive unsound branch test
sim642 Aug 22, 2022
9e52524
Fix witness lifter mishandling Deadcode exceptions
sim642 Aug 22, 2022
256fa17
Move commented-out add code in MapDomain
sim642 Aug 24, 2022
236c76e
Improve HoareDomain and DisjointDomain documentation
sim642 Aug 24, 2022
b16700a
Rename HoareDomain.Set2 -> SetEM
sim642 Aug 24, 2022
2946dcd
Move and document Lval bucket representatives
sim642 Aug 24, 2022
a2d0cea
Use SetDomain.Print for AddressDomain
sim642 Aug 24, 2022
901a709
Fix comment typo in AddressDomain
sim642 Sep 2, 2022
41bfdba
Document SetDomain strong removal
sim642 Sep 2, 2022
f630ebf
Document abstract SetDomain element-wise operations
sim642 Sep 2, 2022
c975d09
Use physical equality short-circuit for AddressDomain.leq
sim642 Sep 2, 2022
cafb5fa
Merge branch 'master' into hoaredomain-new
sim642 Sep 2, 2022
af734d8
Add address domain first field and zero index tests
sim642 Sep 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
75 changes: 74 additions & 1 deletion src/cdomains/addressDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,79 @@ struct
include Printable.Std (* for default invariant, tag, ... *)

module Addr = Lval.NormalLat (Idx)
include HoareDomain.HoarePO (Addr)
module R =
struct
include Addr
type elt = Addr.t

let rec of_elt_offset: Offs.t -> Offs.t =
function
| `NoOffset -> `NoOffset
| `Field (f,o) when not (Offs.is_first_field f) -> `Field (f, of_elt_offset o)
| `Field (_,o) (* zero offsets need to yield the same hash as `NoOffset! *)
| `Index (_,o) -> of_elt_offset o (* index might become top during fp -> might be zero offset *)
(* function
| `NoOffset -> `NoOffset
| `Index (_, o') as o when Offs.cmp_zero_offset o <> `MustNonzero ->
of_elt_offset o'
| `Index (i, o') -> `Index (Idx.top (), of_elt_offset o')
| `Field (_, o') as o when Offs.cmp_zero_offset o <> `MustNonzero ->
of_elt_offset o'
| `Field (f, o') -> `Field (f, of_elt_offset o') (* incorrect *) *)
(* function _ -> `NoOffset (* very crude *) *)
let of_elt = function
| Addr (v, o) -> Addr (v, of_elt_offset o)
| a -> a
end
module R2 =
struct
include IntDomain.Integers (IntOps.NIntOps)
type elt = Addr.t
let of_elt = Addr.hash
end
module C =
struct
type t = Addr.t
let cong x y =
(* ignore (Pretty.eprintf "cong %a %a\n" Addr.pretty x Addr.pretty y); *)
if M.tracing then M.tracei "ad" "cong %a %a\n" Addr.pretty x Addr.pretty y;
(* begin match Addr.to_var_offset y with
| Some (_, `Index (i, `NoOffset)) when Idx.to_int i = Some (Z.of_int 2) -> failwith "THIS"
| _ -> ()
end; *)
let r = match Addr.join x y with
| exception Lattice.Uncomparable -> false
| _ -> true
in
if M.tracing then M.traceu "ad" "-> %B\n" r;
r
end
module RC =
struct
include R
include C
end
module J = SetDomain.Joined (Addr)
module H = HoareDomain.Set2 (Addr)
(* include SensitiveDomain.Pairwise (Addr) (H) (C) *)
include SensitiveDomain.Combined (Addr) (H) (RC)
(* include HoareDomain.HoarePO (Addr) *)

let widen x y =
if M.tracing then M.traceli "ad" "widen %a %a\n" pretty x pretty y;
let r = widen x y in
if M.tracing then M.traceu "ad" "-> %a\n" pretty r;
r
let join x y =
if M.tracing then M.traceli "ad" "join %a %a\n" pretty x pretty y;
let r = join x y in
if M.tracing then M.traceu "ad" "-> %a\n" pretty r;
r
let leq x y =
if M.tracing then M.traceli "ad" "leq %a %a\n" pretty x pretty y;
let r = leq x y in
sim642 marked this conversation as resolved.
Show resolved Hide resolved
if M.tracing then M.traceu "ad" "-> %B\n" r;
r

type field = Addr.field
type idx = Idx.t
Expand All @@ -41,6 +107,7 @@ struct
let not_null = unknown_ptr
let top_ptr = of_list Addr.([UnknownPtr; NullPtr])
let may_be_unknown x = exists (fun e -> e = Addr.UnknownPtr) x
let is_element a x = cardinal x = 1 && Addr.equal (choose x) a
let is_null x = is_element Addr.NullPtr x
let is_not_null x = for_all (fun e -> e <> Addr.NullPtr) x
let may_be_null x = exists (fun e -> e = Addr.NullPtr) x
Expand Down Expand Up @@ -140,4 +207,10 @@ struct

let meet x y = merge join meet x y
let narrow x y = merge (fun x y -> widen x (join x y)) narrow x y

let narrow x y =
if M.tracing then M.traceli "ad" "narrow %a %a\n" pretty x pretty y;
let r = narrow x y in
if M.tracing then M.traceu "ad" "-> %a\n" pretty r;
r
end
12 changes: 6 additions & 6 deletions src/cdomains/lval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ struct
let rec leq x y =
match x, y with
| `NoOffset, `NoOffset -> true
| `NoOffset, x -> cmp_zero_offset x <> `MustNonzero
| x, `NoOffset -> cmp_zero_offset x = `MustZero
| `NoOffset, x -> true
jerhard marked this conversation as resolved.
Show resolved Hide resolved
| `Index (i1,o1), `Index (i2,o2) when Idx.leq i1 i2 -> leq o1 o2
| `Field (f1,o1), `Field (f2,o2) when CilType.Fieldinfo.equal f1 f2 -> leq o1 o2
| _ -> false
Expand All @@ -123,10 +122,9 @@ struct
match x, y with
| `NoOffset, `NoOffset -> `NoOffset
| `NoOffset, x
| x, `NoOffset -> (match cop, cmp_zero_offset x with
| (`Join | `Widen), (`MustZero | `MayZero) -> x
| (`Meet | `Narrow), (`MustZero | `MayZero) -> `NoOffset
| _ -> raise Lattice.Uncomparable)
| x, `NoOffset -> (match cop with
| `Join | `Widen -> x
| `Meet | `Narrow -> `NoOffset)
| `Field (x1,y1), `Field (x2,y2) when CilType.Fieldinfo.equal x1 x2 -> `Field (x1, merge cop y1 y2)
| `Index (x1,y1), `Index (x2,y2) -> `Index (op x1 x2, merge cop y1 y2)
| _ -> raise Lattice.Uncomparable
Expand Down Expand Up @@ -329,6 +327,8 @@ struct
let meet = merge `Meet
let narrow = merge `Narrow

include Lattice.NoBotTop

let pretty_diff () (x,y) = dprintf "%s: %a not leq %a" (name ()) pretty x pretty y
end

Expand Down
14 changes: 8 additions & 6 deletions src/cdomains/valueDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -562,11 +562,12 @@ struct
| (x, `Bot) -> x
| (`Int x, `Int y) -> (try `Int (ID.widen x y) with IntDomain.IncompatibleIKinds m -> Messages.warn ~category:Analyzer "%s" m; `Top)
| (`Float x, `Float y) -> `Float (FD.widen x y)
(* TODO: symmetric widen, wtf? *)
| (`Int x, `Address y)
| (`Address y, `Int x) -> `Address (match ID.to_int x with
jerhard marked this conversation as resolved.
Show resolved Hide resolved
| Some x when BI.equal BI.zero x -> AD.widen AD.null_ptr y
| Some x -> AD.(widen y not_null)
| None -> AD.widen y AD.top_ptr)
| Some x when BI.equal BI.zero x -> AD.widen AD.null_ptr (AD.join AD.null_ptr y)
| Some x -> AD.(widen y (join y not_null))
| None -> AD.widen y (AD.join y AD.top_ptr))
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
| (`Address x, `Address y) -> `Address (AD.widen x y)
| (`Struct x, `Struct y) -> `Struct (Structs.widen_with_fct widen_elem x y)
| (`Union (f,x), `Union (g,y)) -> `Union (match UnionDomain.Field.widen f g with
Expand Down Expand Up @@ -647,11 +648,12 @@ struct
| (x, `Bot) -> x
| (`Int x, `Int y) -> (try `Int (ID.widen x y) with IntDomain.IncompatibleIKinds m -> Messages.warn ~category:Analyzer "%s" m; `Top)
| (`Float x, `Float y) -> `Float (FD.widen x y)
(* TODO: symmetric widen, wtf? *)
| (`Int x, `Address y)
| (`Address y, `Int x) -> `Address (match ID.to_int x with
| Some x when BI.equal x BI.zero -> AD.widen AD.null_ptr y
| Some x -> AD.(widen y not_null)
| None -> AD.widen y AD.top_ptr)
| Some x when BI.equal x BI.zero -> AD.widen AD.null_ptr (AD.join AD.null_ptr y)
| Some x -> AD.(widen y (join y not_null))
| None -> AD.widen y (AD.join y AD.top_ptr))
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
| (`Address x, `Address y) -> `Address (AD.widen x y)
| (`Struct x, `Struct y) -> `Struct (Structs.widen x y)
| (`Union (f,x), `Union (g,y)) -> `Union (match UnionDomain.Field.widen f g with
Expand Down
38 changes: 35 additions & 3 deletions src/domains/hoareDomain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ struct
let union x y = join x y
let iter f m = Map.iter (fun _ -> List.iter f) m

let is_element e m = Map.cardinal m = 1 && snd (Map.choose m) = [e]

(* Lattice *)
let bot () = Map.empty
let is_bot = Map.is_empty
Expand Down Expand Up @@ -167,6 +165,7 @@ struct
List.iter (E.printXml f) (elements x);
BatPrintf.fprintf f "</set>\n</value>\n"
end
[@@deprecated]


module type SetS =
Expand Down Expand Up @@ -194,7 +193,7 @@ struct
let narrow = product_bot (fun x y -> if B.leq y x then B.narrow x y else x)

let add x a = if mem x a then a else add x a (* special mem! *)
let remove x a = unsupported "Set.remove"
let remove x a = filter (fun y -> not (B.leq y x)) a
michael-schwarz marked this conversation as resolved.
Show resolved Hide resolved
let join a b = union a b |> reduce
let union _ _ = unsupported "Set.union"
let inter _ _ = unsupported "Set.inter"
Expand Down Expand Up @@ -338,3 +337,36 @@ struct
(cardinal s2)
end
end


module Set2 (E: Lattice.S): SetDomain.S with type elt = E.t =
struct
module H = Set (E)
include H


(* version of widen which doesn't use E.bot *)
let product_widen (op: elt -> elt -> elt option) a b = (* assumes b to be bigger than a *)
let xs,ys = elements a, elements b in
List.concat_map (fun x -> List.filter_map (fun y -> op x y) ys) xs |> fun x -> join b (of_list x)
let widen = product_widen (fun x y -> if E.leq x y then Some (E.widen x y) else None)

(* widen is actually extrapolation operator, so define connector-based widening instead *)
let leq_em s1 s2 =
is_bot s1 || leq s1 s2 && for_all (fun e2 -> exists (fun e1 -> E.leq e1 e2) s1) s2
let join_em s1 s2 =
join s1 s2
|> elements
|> BatList.reduce E.join
|> singleton

let widen s1 s2 =
assert (leq s1 s2);
let s2' =
if leq_em s1 s2 then
s2
else
join_em s1 s2
in
widen s1 s2'
end
14 changes: 10 additions & 4 deletions src/domains/lattice.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ end
module Unit = UnitConf (struct let name = "()" end)


module NoBotTop =
struct
let top () = raise TopValue
let is_top _ = false
let bot () = raise BotValue
let is_bot _ = false
end


module Fake (Base: Printable.S) =
struct
include Base
Expand All @@ -70,10 +79,7 @@ struct
let meet x y =
if equal x y then x else raise (Unsupported "fake meet")
let narrow = meet
let top () = raise (Unsupported "fake top")
let is_top _ = false
let bot () = raise (Unsupported "fake bot")
let is_bot _ = false
include NoBotTop

let pretty_diff () (x,y) =
Pretty.dprintf "%s: %a not equal %a" (Base.name ()) pretty x pretty y
Expand Down