diff --git a/Makefile b/Makefile index ce5d740b6d4f2ffd7428765694e2e42949dd6b68..334437fc823b2fda73ba2f525a1d0abe5a13e074 100644 --- a/Makefile +++ b/Makefile @@ -878,7 +878,7 @@ PLUGIN_CMO:= slevel/split_strategy value_parameters \ slevel/per_stmt_slevel \ utils/library_functions \ utils/eval_typ utils/backward_formals \ - alarmset eval utils/structure \ + alarmset eval utils/structure utils/abstract \ values/value_product values/location_lift \ values/cvalue_forward values/cvalue_backward \ values/main_values values/main_locations \ diff --git a/headers/header_spec.txt b/headers/header_spec.txt index f5f65ba9305df53bb4a95afcc297f6bfe441ab7a..b66be1d6251f0bfde9c04b103943158952b9c1c6 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -1272,6 +1272,8 @@ src/plugins/value/slevel/split_strategy.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/slevel/split_strategy.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/test.assert.sh: .ignore src/plugins/value/test.sh: .ignore +src/plugins/value/utils/abstract.ml: CEA_LGPL_OR_PROPRIETARY +src/plugins/value/utils/abstract.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/backward_formals.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/backward_formals.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/eval_typ.ml: CEA_LGPL_OR_PROPRIETARY diff --git a/src/plugins/value/domains/abstract_domain.mli b/src/plugins/value/domains/abstract_domain.mli index 9bf4563c8cd4e13948555f4446989e91b8c2687d..4c77a1475887504958c8884cd540d0bdf5697822 100644 --- a/src/plugins/value/domains/abstract_domain.mli +++ b/src/plugins/value/domains/abstract_domain.mli @@ -396,73 +396,12 @@ module type S = sig val initialize_variable_using_type: init_kind -> varinfo -> t -> t include Recycle with type t := t -end - - -(** Keys identify abstract domains through the type of their abstract values. *) -type 'a key = 'a Structure.Key_Domain.key - -(** Describes the internal structure of a domain. - Used internally to automatically generate efficient accessors from a - generic abstract domain, which may be a combination of several domains, - to a specific one. *) -type 'a structure = 'a Structure.Key_Domain.structure = - | Void : 'a structure - | Leaf : 'a key -> 'a structure - | Node : 'a structure * 'b structure -> ('a * 'b) structure - -(** - For a simple 'leaf' domain, the structure should be: - [let key = Structure.Key_Domain.create_key "name_of_the_domain";; - let structure = Leaf key;;] - - Then, the key should be exported by the domain, to allow the use of the - functions defined in the {!Interface} interface below. - - A compound domain may use the {!Node} constructor to provide a separate - access to each of its parts. - - A domain can also use the {!Void} constructor to prevent access to itself. -*) - -(** Structure of a domain. *) -module type S_with_Structure = sig - include S - - (** A structure matching the type of the domain. *) - val structure : t structure (** Category for the messages about the domain. Must be created through {!Value_parameters.register_category}. *) val log_category : Value_parameters.category end -(** External interface of a domain, with accessors. - Automatically built by the functor {!Structure.Open}. - When a generic domain is a combination of several domains, these functions - allow interacting with its subparts. Note that their behavior is undefined - if the overall domain contains several times the same domain. *) -module type Interface = sig - type t - - (** Tests whether a key belongs to the domain. *) - val mem : 'a key -> bool - - (** For a key of type [k key]: - - if the states of this domain (of type [t]) contain a part (of type [k]) - from the domain identified by the key, - then [get key] returns an accessor for this part of a state. - - otherwise, [get key] returns None. *) - val get : 'a key -> (t -> 'a) option - - (** For a key of type [k key]: - - if the states of this domain (of type [t]) contain a part (of type [k]) - from the domain identified by the key, - then [set key d state] returns the state [state] in which this part - has been replaced by [d]. - - otherwise, [set key _] is the identity function. *) - val set : 'a key -> 'a -> t -> t -end (** Automatic storage of the states computed during the analysis. *) module type Store = sig @@ -487,7 +426,7 @@ end (** Full implementation of domains. Automatically built by {!Domain_builder.Complete} from an {!S_with_Structure} domain. *) module type Internal = sig - include S_with_Structure + include S module Store: Store with type state := state (** This function is called after the analysis. The argument is the state @@ -497,11 +436,14 @@ module type Internal = sig val post_analysis: t or_bottom -> unit end -(** Final interface of domains, as generated and used by Eva, with generic - accessors for domains. *) -module type External = sig +type 't key = 't Structure.Key_Domain.key + +(** Signature for a leaf module of a domain. *) +module type Leaf = sig include Internal - include Interface with type t := state + + (** The key identifies the domain and the type [t] of its states. *) + val key: t key end diff --git a/src/plugins/value/domains/apron/apron_domain.ko.ml b/src/plugins/value/domains/apron/apron_domain.ko.ml index 9ccb3680e2919874b7ad15a85c8b3c597e39083d..cde2dc82ad67131375f9493d47384e256eb708d1 100644 --- a/src/plugins/value/domains/apron/apron_domain.ko.ml +++ b/src/plugins/value/domains/apron/apron_domain.ko.ml @@ -22,11 +22,14 @@ let ok = false -module type S = Abstract_domain.Internal +module type S = Abstract_domain.Leaf with type value = Main_values.Interval.t and type location = Precise_locs.precise_location -module U = Unit_domain.Make (Main_values.Interval) (Main_locations.PLoc) +module U = struct + include Unit_domain.Make (Main_values.Interval) (Main_locations.PLoc) + let key = Structure.Key_Domain.create_key "dummy_apron" +end module Octagon = U module Box = U @@ -34,14 +37,6 @@ module Polka_Loose = U module Polka_Strict = U module Polka_Equalities = U -let dummy_key = Structure.Key_Domain.create_key "dummy_apron" -let octagon_key = dummy_key -let box_key = dummy_key -let polka_loose_key = dummy_key -let polka_strict_key = dummy_key -let polka_equalities_key = dummy_key - - (* Local Variables: compile-command: "make -C ../../../.." diff --git a/src/plugins/value/domains/apron/apron_domain.mli b/src/plugins/value/domains/apron/apron_domain.mli index 19c6611afb1159e90e569e04971eec187da1bbab..b330002eca963b2f27dc42381dd90b7ae6379d5f 100644 --- a/src/plugins/value/domains/apron/apron_domain.mli +++ b/src/plugins/value/domains/apron/apron_domain.mli @@ -28,7 +28,7 @@ val ok : bool (** Signature of an Apron domain in Eva. *) -module type S = Abstract_domain.Internal +module type S = Abstract_domain.Leaf with type value = Main_values.Interval.t and type location = Precise_locs.precise_location @@ -51,16 +51,6 @@ module Polka_Strict : S (** Linear equalities. *) module Polka_Equalities : S - -(** Domain keys for the Apron domains in Eva. *) - -val octagon_key : Octagon.t Abstract_domain.key -val box_key : Box.t Abstract_domain.key -val polka_loose_key : Polka_Loose.t Abstract_domain.key -val polka_strict_key : Polka_Strict.t Abstract_domain.key -val polka_equalities_key : Polka_Equalities.t Abstract_domain.key - - (* Local Variables: compile-command: "make -C ../../../.." diff --git a/src/plugins/value/domains/apron/apron_domain.ok.ml b/src/plugins/value/domains/apron/apron_domain.ok.ml index e69f47ab8625886339479d8da73957603665d6aa..160d5ced13653b530c18a30a634a301484a5f957 100644 --- a/src/plugins/value/domains/apron/apron_domain.ok.ml +++ b/src/plugins/value/domains/apron/apron_domain.ok.ml @@ -32,7 +32,7 @@ let ok = true let debug = false -module type S = Abstract_domain.Internal +module type S = Abstract_domain.Leaf with type value = Main_values.Interval.t and type location = Precise_locs.precise_location @@ -362,7 +362,6 @@ module Make type t val manager: t Manager.t val name: string - val key: t Abstract1.t Abstract_domain.key end) = struct @@ -371,8 +370,6 @@ module Make type location = Precise_locs.precise_location let man = Man.manager - - let structure = Abstract_domain.Leaf Man.key let log_category = dkey let empty_env = Environment.make [||] [||] @@ -725,44 +722,32 @@ module Make end -let octagon_key = Structure.Key_Domain.create_key "apron-octagon" -let box_key = Structure.Key_Domain.create_key "apron-box" -let polka_loose_key = Structure.Key_Domain.create_key "polka-loose" -let polka_strict_key = Structure.Key_Domain.create_key "polka-strict" -let polka_equalities_key = Structure.Key_Domain.create_key "polka-equalities" - - module Apron_Octagon = struct type t = Oct.t let manager = Oct.manager_alloc () let name = "Apron octagon domain" - let key = octagon_key end module Apron_Box = struct type t = Box.t let manager = Box.manager_alloc () let name = "Apron box domain" - let key = box_key end module Apron_Polka_Loose = struct type t = Polka.loose Polka.t let manager = Polka.manager_alloc_loose () let name = "Polka loose polyhedra domain" - let key = polka_loose_key end module Apron_Polka_Strict = struct type t = Polka.strict Polka.t let manager = Polka.manager_alloc_strict () let name = "Polka strict polyhedra domain" - let key = polka_strict_key end module Apron_Polka_Equalities = struct type t = Polka.equalities Polka.t let manager = Polka.manager_alloc_equalities () let name = "Polka linear equalities domain" - let key = polka_equalities_key end (** Apron manager allocation changes the rounding mode. *) diff --git a/src/plugins/value/domains/cvalue/cvalue_domain.ml b/src/plugins/value/domains/cvalue/cvalue_domain.ml index 841850c4fefb3bc6b3bc6b678eefa8887bf517fa..3c0579fa6462ea7496f28af5b5ebc819b84f0cec 100644 --- a/src/plugins/value/domains/cvalue/cvalue_domain.ml +++ b/src/plugins/value/domains/cvalue/cvalue_domain.ml @@ -29,7 +29,7 @@ let extract get = match get key with | None -> fun _ -> Cvalue.Model.top | Some get -> function | `Bottom -> Cvalue.Model.bottom - | `Value state -> get state + | `Value state -> fst (get state) module Model = struct @@ -168,10 +168,6 @@ module State = struct type state = Model.t * Locals_scoping.clobbered_set - let structure = - Abstract_domain.Node (Abstract_domain.Leaf key, - Abstract_domain.Leaf Locals_scoping.key) - let log_category = Value_parameters.dkey_cvalue_domain include Datatype.Make_with_collections ( @@ -193,6 +189,7 @@ module State = struct end ) let name = "Cvalue domain" + let key = key type value = Model.value type location = Model.location @@ -562,12 +559,12 @@ module Subpart = struct let hash = Model.hash_subtree let equal = Model.equal_subtree end -let distinct_subpart a b = +let distinct_subpart (a, _) (b, _) = if Model.equal a b then None else try Model.comp_prefixes a b; None with Model.Found_prefix (p, s1, s2) -> Some (p, s1, s2) -let find_subpart s prefix = Model.find_prefix s prefix +let find_subpart (s, _) prefix = Model.find_prefix s prefix (* Local Variables: diff --git a/src/plugins/value/domains/cvalue/cvalue_domain.mli b/src/plugins/value/domains/cvalue/cvalue_domain.mli index 34436ded0ad5db8a2d0b97d157f0d802891256a4..bd1284006ff3f389db475654aee11f3e21604cf4 100644 --- a/src/plugins/value/domains/cvalue/cvalue_domain.mli +++ b/src/plugins/value/domains/cvalue/cvalue_domain.mli @@ -22,15 +22,14 @@ (** Main domain of the Value Analysis. *) -module State : Abstract_domain.Internal +module State : Abstract_domain.Leaf with type value = Main_values.CVal.t and type location = Main_locations.PLoc.location - - -val key : Cvalue.Model.t Abstract_domain.key + and type state = Cvalue.Model.t * Locals_scoping.clobbered_set val extract : - (Cvalue.Model.t Abstract_domain.key -> ('state -> Cvalue.Model.t) option) -> + (State.t Structure.Key_Domain.key -> + ('state -> State.t) option) -> 'state Eval.or_bottom -> Cvalue.Model.t val inject : Cvalue.Model.t -> State.t @@ -42,8 +41,8 @@ val project : State.t -> Cvalue.Model.t type prefix module Subpart : Hashtbl.HashedType val distinct_subpart : - Cvalue.Model.t -> Cvalue.Model.t -> (prefix * Subpart.t * Subpart.t) option -val find_subpart : Cvalue.Model.t -> prefix -> Subpart.t option + State.t -> State.t -> (prefix * Subpart.t * Subpart.t) option +val find_subpart : State.t -> prefix -> Subpart.t option diff --git a/src/plugins/value/domains/cvalue/locals_scoping.ml b/src/plugins/value/domains/cvalue/locals_scoping.ml index 2059c345c71b2421ed931990f7471fccdfa83ad5..0399ececdacea419c547292619239e0b51aceea7 100644 --- a/src/plugins/value/domains/cvalue/locals_scoping.ml +++ b/src/plugins/value/domains/cvalue/locals_scoping.ml @@ -27,8 +27,6 @@ type clobbered_set = { mutable clob: Base.SetLattice.t } -let key = Structure.Key_Domain.create_key "clobbered_set" - let structural_descr = let open Structural_descr in t_record [| Base.SetLattice.packed_descr |] diff --git a/src/plugins/value/domains/cvalue/locals_scoping.mli b/src/plugins/value/domains/cvalue/locals_scoping.mli index e0b8c5d181d57181580186b48c8a832594d15550..8f0835453855fa211165d61038556ce98f03a81d 100644 --- a/src/plugins/value/domains/cvalue/locals_scoping.mli +++ b/src/plugins/value/domains/cvalue/locals_scoping.mli @@ -30,8 +30,6 @@ type clobbered_set = { mutable clob: Base.SetLattice.t } -val key: clobbered_set Abstract_domain.key - val structural_descr: Structural_descr.t val bottom: unit -> clobbered_set diff --git a/src/plugins/value/domains/domain_builder.ml b/src/plugins/value/domains/domain_builder.ml index b27b01329e10386ad60dee893ca52c897b1d10a5..7406f3753ddcdd15481c6defa1d9e2a36c403c12 100644 --- a/src/plugins/value/domains/domain_builder.ml +++ b/src/plugins/value/domains/domain_builder.ml @@ -22,7 +22,7 @@ module type InputDomain = sig - include Abstract_domain.S_with_Structure + include Abstract_domain.S val storage: unit -> bool end @@ -33,6 +33,9 @@ module Complete include Domain module Store = Domain_store.Make (Domain) + let key: Domain.t Structure.Key_Domain.key = + Structure.Key_Domain.create_key Domain.name + let post_analysis _state = () end @@ -57,7 +60,6 @@ module Make_Minimal include Domain - let structure = Abstract_domain.Void let log_category = Value_parameters.register_category ("d-" ^ name) type value = Value.t @@ -185,7 +187,6 @@ module Complete_Simple_Cvalue (Domain: Simpler_domains.Simple_Cvalue) (Domain) (struct let module_name = Domain.name end) : Datatype.S_with_collections with type t := t) - let structure = Abstract_domain.Void let log_category = Value_parameters.register_category ("d-" ^ name) type value = Cvalue.V.t diff --git a/src/plugins/value/domains/domain_builder.mli b/src/plugins/value/domains/domain_builder.mli index 7d3b426a606878abe05699292d827739fcec4948..1eddbb4b8b52625248ac77e374a6af904047cdf5 100644 --- a/src/plugins/value/domains/domain_builder.mli +++ b/src/plugins/value/domains/domain_builder.mli @@ -24,34 +24,34 @@ simplified interfaces. *) module type InputDomain = sig - include Abstract_domain.S_with_Structure + include Abstract_domain.S val storage: unit -> bool end module Complete (Domain: InputDomain) - : Abstract_domain.Internal with type state = Domain.state - and type value = Domain.value - and type location = Domain.location + : Abstract_domain.Leaf with type state = Domain.state + and type value = Domain.value + and type location = Domain.location module Complete_Minimal (Value: Abstract_value.S) (Location: Abstract_location.S) (Domain: Simpler_domains.Minimal) - : Abstract_domain.Internal with type value = Value.t - and type location = Location.location - and type state = Domain.t + : Abstract_domain.Leaf with type value = Value.t + and type location = Location.location + and type state = Domain.t module Complete_Minimal_with_datatype (Value: Abstract_value.S) (Location: Abstract_location.S) (Domain: Simpler_domains.Minimal_with_datatype) - : Abstract_domain.Internal with type value = Value.t - and type location = Location.location - and type state = Domain.t + : Abstract_domain.Leaf with type value = Value.t + and type location = Location.location + and type state = Domain.t module Complete_Simple_Cvalue (Domain: Simpler_domains.Simple_Cvalue) - : Abstract_domain.Internal with type value = Cvalue.V.t - and type location = Precise_locs.precise_location - and type state = Domain.t + : Abstract_domain.Leaf with type value = Cvalue.V.t + and type location = Precise_locs.precise_location + and type state = Domain.t diff --git a/src/plugins/value/domains/domain_lift.ml b/src/plugins/value/domains/domain_lift.ml index 02eaa96e98d63b5f8cccfe3bfa8463d6565ef361..d53990a56ccd8c1449c45704adea367eac5b0f35 100644 --- a/src/plugins/value/domains/domain_lift.ml +++ b/src/plugins/value/domains/domain_lift.ml @@ -45,7 +45,6 @@ module Make include (Domain : Datatype.S_with_collections with type t = Domain.t) include (Domain : Abstract_domain.Lattice with type state = Domain.state) - let structure = Domain.structure let log_category = Domain.log_category type value = Convert.extended_value diff --git a/src/plugins/value/domains/domain_product.ml b/src/plugins/value/domains/domain_product.ml index e596deec5d4fb9c3ec0864d3e1db015137fa16de..d35d7c7c7911e44930051c246e6e599cacec7c37 100644 --- a/src/plugins/value/domains/domain_product.ml +++ b/src/plugins/value/domains/domain_product.ml @@ -51,8 +51,6 @@ module Make (struct let module_name = name end) type state = t - let structure = Abstract_domain.Node (Left.structure, Right.structure) - let log_category = product_category let top = Left.top, Right.top diff --git a/src/plugins/value/domains/equality/equality_domain.ml b/src/plugins/value/domains/equality/equality_domain.ml index 7ccb02c97211ab9dfbf100b5cf16abd9c45358d0..7186aaebe57942d239821101d28e1f9770848930 100644 --- a/src/plugins/value/domains/equality/equality_domain.ml +++ b/src/plugins/value/domains/equality/equality_domain.ml @@ -122,9 +122,8 @@ module Internal = struct type state = t let name = "Equality domain" - let key = Structure.Key_Domain.create_key "equality_domain" - let structure : t Abstract_domain.structure = Abstract_domain.Leaf key let log_category = dkey + let key = Structure.Key_Domain.create_key "equality_domain" type equalities = Equality.Set.t let project (t, _, _) = t @@ -180,13 +179,13 @@ module Store = Domain_store.Make (Internal) (* ------------------------- Abstract Domain -------------------------------- *) module Make - (Value : Abstract_value.External) + (Value : Abstract.Value.External) = struct include Internal module Store = Store - let get_cvalue = Value.get Main_values.cvalue_key + let get_cvalue = Value.get Main_values.CVal.key type value = Value.t type location = Precise_locs.precise_location @@ -218,7 +217,7 @@ module Make let c = get v in if Cvalue.V.is_imprecise c then let c' = Cvalue.V.topify_with_origin Origin.top c in - Value.set Main_values.cvalue_key c' v + Value.set Main_values.CVal.key c' v else v let coop_eval oracle equalities atom_src = diff --git a/src/plugins/value/domains/equality/equality_domain.mli b/src/plugins/value/domains/equality/equality_domain.mli index 6f6d041654125ff27303bcd95cd853297b8ba836..1242e9d2e9cc9af841e56d5ffcad96c5c0595747 100644 --- a/src/plugins/value/domains/equality/equality_domain.mli +++ b/src/plugins/value/domains/equality/equality_domain.mli @@ -31,10 +31,9 @@ type call_init_state = | ISEmpty (** completely empty state, without impact on Memexec. *) -module Make (Value : Abstract_value.External) : sig - include Abstract_domain.Internal with type value = Value.t - and type location = Precise_locs.precise_location - val key : t Abstract_domain.key +module Make (Value : Abstract.Value.External) : sig + include Abstract_domain.Leaf with type value = Value.t + and type location = Precise_locs.precise_location val pretty_debug : Format.formatter -> t -> unit diff --git a/src/plugins/value/domains/gauges/gauges_domain.ml b/src/plugins/value/domains/gauges/gauges_domain.ml index 1af3127519259cc44ffd7db880c28f39dc8983da..e45fc726212b250492260e4c551bc5c1bed3dea4 100644 --- a/src/plugins/value/domains/gauges/gauges_domain.ml +++ b/src/plugins/value/domains/gauges/gauges_domain.ml @@ -1120,7 +1120,7 @@ end let dkey = Value_parameters.register_category "d-gauges" -module D_Impl : Abstract_domain.S_with_Structure +module D_Impl : Abstract_domain.S with type state = G.t and type value = Cvalue.V.t and type location = Precise_locs.precise_location @@ -1132,8 +1132,6 @@ module D_Impl : Abstract_domain.S_with_Structure include G let name = "Gauges domain" - - let structure = Abstract_domain.Void let log_category = dkey let empty _ = G.empty diff --git a/src/plugins/value/domains/gauges/gauges_domain.mli b/src/plugins/value/domains/gauges/gauges_domain.mli index a1609d838a046745346cd36f02e063314057b88a..f51fdfbc660171bd5485c37869384790319e43e1 100644 --- a/src/plugins/value/domains/gauges/gauges_domain.mli +++ b/src/plugins/value/domains/gauges/gauges_domain.mli @@ -23,6 +23,6 @@ (** Gauges domain ("Arnaud Venet: The Gauge Domain: Scalable Analysis of Linear Inequality Invariants. CAV 2012") *) -module D: Abstract_domain.Internal +module D: Abstract_domain.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location diff --git a/src/plugins/value/domains/inout_domain.ml b/src/plugins/value/domains/inout_domain.ml index 12ba3cd152852bbd7ea98e40b0921ae2110bc5a6..1a5a4888c93f0f23d46045a7048f47755e2075b2 100644 --- a/src/plugins/value/domains/inout_domain.ml +++ b/src/plugins/value/domains/inout_domain.ml @@ -204,8 +204,6 @@ module Transfer = struct end -let key = Structure.Key_Domain.create_key "inout domain" - module Internal (*: Domain_builder.InputDomain with type state = inout @@ -221,7 +219,7 @@ module Internal include Abstract_domain.Lattice with type state := state end) - let structure : t Abstract_domain.structure = Abstract_domain.Leaf key + let name = "inout" let log_category = Value_parameters.register_category "d-inout" let enter_scope _kf _vars state = state diff --git a/src/plugins/value/domains/inout_domain.mli b/src/plugins/value/domains/inout_domain.mli index 0304f94f6900c3178afd03ca5c1d3534896a70a6..f759f59bfe6bff258657a4623bfdec01048222e4 100644 --- a/src/plugins/value/domains/inout_domain.mli +++ b/src/plugins/value/domains/inout_domain.mli @@ -22,8 +22,6 @@ (** Computation of inputs of outputs. *) -module D: Abstract_domain.Internal +module D: Abstract_domain.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location - -val key: D.t Abstract_domain.key diff --git a/src/plugins/value/domains/numerors/numerors_domain.mli b/src/plugins/value/domains/numerors/numerors_domain.mli index 00b7a2ea9727b69b5353a6f10faf09750e7667cf..c00510fa3097c46ce53ddc5288b6bb2e0f618641 100644 --- a/src/plugins/value/domains/numerors/numerors_domain.mli +++ b/src/plugins/value/domains/numerors/numerors_domain.mli @@ -35,15 +35,15 @@ val ok: bool numerors values on casts from integer to floating-point values. Fails if numerors domain is not available. *) val add_numerors_value: - (module Abstract_value.Internal) -> (module Abstract_value.Internal) + (module Abstract.Value.Internal) -> (module Abstract.Value.Internal) (* From a given abstract value product, creates the reduction function that reduces numerors values by using cvalues. Returns the identity if the given value product does not contain numerors and cvalue componants. *) val reduce_error: - (module Abstract_value.External with type t = 'v) -> ('v -> 'v) + (module Abstract.Value.External with type t = 'v) -> ('v -> 'v) (** Returns the numerors domain module, if available. Fails otherwise. *) val numerors_domain: - unit -> (module Abstract_domain.Internal with type value = value - and type location = location) + unit -> (module Abstract_domain.Leaf with type value = value + and type location = location) diff --git a/src/plugins/value/domains/numerors/numerors_domain.ok.ml b/src/plugins/value/domains/numerors/numerors_domain.ok.ml index cf8e73a78c435b8f993f61ab80c07057b10d60d4..8603b8643b06d45928d41616d7db798b65d68bef 100644 --- a/src/plugins/value/domains/numerors/numerors_domain.ok.ml +++ b/src/plugins/value/domains/numerors/numerors_domain.ok.ml @@ -27,7 +27,7 @@ open Cil_types type value = Numerors_value.t type location = Precise_locs.precise_location -let value_key = Numerors_value.error_key +let value_key = Numerors_value.key let ok = true @@ -87,12 +87,15 @@ module Numerors_Value = struct ] end -let add_numerors_value (module Value: Abstract_value.Internal) = +let add_numerors_value (module Value: Abstract.Value.Internal) = let module External_Value = Structure.Open (Structure.Key_Value) (Value) in let module V = struct include Value_product.Make (Value) (Numerors_value) - let forward_cast = match External_Value.get Main_values.cvalue_key with + let structure = + Abstract.Value.(Node (Value.structure, Leaf Numerors_value.key)) + + let forward_cast = match External_Value.get Main_values.CVal.key with | None -> forward_cast | Some get_cvalue -> fun ~src_type ~dst_type (value, num) -> @@ -116,13 +119,13 @@ let add_numerors_value (module Value: Abstract_value.Internal) = in value', num end in - (module V: Abstract_value.Internal) + (module V: Abstract.Value.Internal) -let reduce_error (type v) (module V: Abstract_value.External with type t = v) = - match V.get Numerors_value.error_key, V.get Main_values.cvalue_key with +let reduce_error (type v) (module V: Abstract.Value.External with type t = v) = + match V.get Numerors_value.key, V.get Main_values.CVal.key with | Some get_error, Some get_cvalue -> begin - let set_error = V.set Numerors_value.error_key in + let set_error = V.set Numerors_value.key in fun t -> let cvalue = get_cvalue t in try @@ -159,5 +162,5 @@ end let numerors_domain () = Value_parameters.warning "The numerors domain is experimental."; - (module Domain: Abstract_domain.Internal with type value = value - and type location = location) + (module Domain: Abstract_domain.Leaf with type value = value + and type location = location) diff --git a/src/plugins/value/domains/offsm_domain.ml b/src/plugins/value/domains/offsm_domain.ml index 8ab4ee60ca741522d565be563559c1224d23022d..f491384582b905f2aba39ffa65dc80f073344669 100644 --- a/src/plugins/value/domains/offsm_domain.ml +++ b/src/plugins/value/domains/offsm_domain.ml @@ -103,7 +103,6 @@ module Internal : Domain_builder.InputDomain end) let name = "Bitwise domain" - let structure = Abstract_domain.Void let log_category = dkey let empty _ = Memory.empty_map diff --git a/src/plugins/value/domains/offsm_domain.mli b/src/plugins/value/domains/offsm_domain.mli index 4567fc14d3f21c1ad2db640e9264fe6ec387e4cb..8833d4b88cb93b0134e3239aa139a3c6a34585a5 100644 --- a/src/plugins/value/domains/offsm_domain.mli +++ b/src/plugins/value/domains/offsm_domain.mli @@ -20,6 +20,6 @@ (* *) (**************************************************************************) -module D : Abstract_domain.Internal +module D : Abstract_domain.Leaf with type value = Offsm_value.offsm_or_top and type location = Precise_locs.precise_location diff --git a/src/plugins/value/domains/printer_domain.mli b/src/plugins/value/domains/printer_domain.mli index 5355cebbd9cbf82b76690098e670e0af76855c9c..febfc6902d6a8cdf0d0bee4a199bbdadd5cc094d 100644 --- a/src/plugins/value/domains/printer_domain.mli +++ b/src/plugins/value/domains/printer_domain.mli @@ -23,5 +23,5 @@ (** An abstract domain built on top of the Simpler_domains.Simple_Cvalue interface that just prints the transfer functions called by the engine during an analysis. *) -include Abstract_domain.Internal with type value = Cvalue.V.t - and type location = Precise_locs.precise_location +include Abstract_domain.Leaf with type value = Cvalue.V.t + and type location = Precise_locs.precise_location diff --git a/src/plugins/value/domains/sign_domain.mli b/src/plugins/value/domains/sign_domain.mli index fafc9f18c67cf1cd72ee5d88375dfce1631f8fe6..b32803feb652aad71ea799b02aff6a7c733f6b40 100644 --- a/src/plugins/value/domains/sign_domain.mli +++ b/src/plugins/value/domains/sign_domain.mli @@ -22,5 +22,5 @@ (** Abstraction of the sign of integer variables. *) -include Abstract_domain.Internal with type value = Sign_value.t - and type location = Precise_locs.precise_location +include Abstract_domain.Leaf with type value = Sign_value.t + and type location = Precise_locs.precise_location diff --git a/src/plugins/value/domains/simple_memory.ml b/src/plugins/value/domains/simple_memory.ml index f312b589f11a835903ac4080566ce7f14b81df3a..ea1757685829577ec77aa94c1c1de8ff79dc8ce2 100644 --- a/src/plugins/value/domains/simple_memory.ml +++ b/src/plugins/value/domains/simple_memory.ml @@ -188,9 +188,6 @@ module Make_Internal (Info: sig val name: string end) (Value: Value) = struct type value = Value.t type location = Precise_locs.precise_location - let key = Structure.Key_Domain.create_key (Info.name ^ " domain") - let structure : t Abstract_domain.structure = Abstract_domain.Leaf key - let log_category = Value_parameters.register_category ("d-" ^ Info.name) let widen _kf _stmt = widen diff --git a/src/plugins/value/domains/simple_memory.mli b/src/plugins/value/domains/simple_memory.mli index e45eef5cb3a61dcb648a8934330ceabd2d36552f..0ea8a003a607d3271ff50d8c4909948c933b520b 100644 --- a/src/plugins/value/domains/simple_memory.mli +++ b/src/plugins/value/domains/simple_memory.mli @@ -106,8 +106,8 @@ module Make_Domain (Value: Value) : sig - include Abstract_domain.Internal with type value = Value.t - and type location = Precise_locs.precise_location + include Abstract_domain.Leaf with type value = Value.t + and type location = Precise_locs.precise_location include S with type t := t and type value := Value.t diff --git a/src/plugins/value/domains/symbolic_locs.ml b/src/plugins/value/domains/symbolic_locs.ml index 42db4cd7cb58a9c6b6cd3cd75b24f28ab2bd0149..00220370476099169b87412b86f2b397e6574c2f 100644 --- a/src/plugins/value/domains/symbolic_locs.ml +++ b/src/plugins/value/domains/symbolic_locs.ml @@ -472,7 +472,6 @@ module Internal : Domain_builder.InputDomain end) let name = "Symbolic locations domain" - let structure = Abstract_domain.Void let log_category = dkey let empty _ = Memory.empty_map diff --git a/src/plugins/value/domains/symbolic_locs.mli b/src/plugins/value/domains/symbolic_locs.mli index 06cda3ce5eb47f2d1ac33fdfe85205c3dbb1afbb..7cebf7b9f4cb6083bf3625b520be6bf5c1e30ae1 100644 --- a/src/plugins/value/domains/symbolic_locs.mli +++ b/src/plugins/value/domains/symbolic_locs.mli @@ -23,6 +23,6 @@ (** Domain that store information on non-precise l-values such as [t[i]] or [*p] when [i] or [p] is not exact. *) -module D: Abstract_domain.Internal +module D: Abstract_domain.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location diff --git a/src/plugins/value/domains/traces_domain.ml b/src/plugins/value/domains/traces_domain.ml index 68f7b320300808fd20c819154f7fcd6d4b8e4705..f7d5946d2dd0477f135ef6c82b6f6190410c1156 100644 --- a/src/plugins/value/domains/traces_domain.ml +++ b/src/plugins/value/domains/traces_domain.ml @@ -846,8 +846,6 @@ let rec complete_graph (graph:Graph.t) = ) graph Graph.empty -let key = Structure.Key_Domain.create_key "traces domain" - module Internal = struct type nonrec state = state type value = Cvalue.V.t @@ -858,7 +856,6 @@ module Internal = struct include Abstract_domain.Lattice with type state := state end) - let structure : t Abstract_domain.structure = Abstract_domain.Leaf key let log_category = Value_parameters.register_category "d-traces" type origin = unit @@ -1271,8 +1268,7 @@ let output_dot filename state = close_out out module D = struct - include Internal - module Store = Domain_store.Make(Internal) + include Domain_builder.Complete (Internal) let post_analysis state = let return_stmt = Kernel_function.find_return (fst (Globals.entry_point ())) in diff --git a/src/plugins/value/domains/traces_domain.mli b/src/plugins/value/domains/traces_domain.mli index 7319b2f20bc6c107e0e135a976e75355c26e0a7c..a1c57a5359d505bcb8ba41a06b9ab4d7003f649f 100644 --- a/src/plugins/value/domains/traces_domain.mli +++ b/src/plugins/value/domains/traces_domain.mli @@ -71,7 +71,7 @@ val current: state -> loops val globals: state -> Cil_types.varinfo list val entry_formals: state -> Cil_types.varinfo list -module D: Abstract_domain.Internal +module D: Abstract_domain.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location and type state = state diff --git a/src/plugins/value/domains/unit_domain.ml b/src/plugins/value/domains/unit_domain.ml index 4bb14526c7b277ba0348fd36954e862c6d997ab4..729932cbcb7a79c002c3134b0ccbdad052e6c9ad 100644 --- a/src/plugins/value/domains/unit_domain.ml +++ b/src/plugins/value/domains/unit_domain.ml @@ -28,8 +28,8 @@ module Static = struct type state = t let name = "Unit domain" - let structure = Abstract_domain.Void let log_category = log_key + let structure = Abstract.Domain.Void let top = () let is_included _ _ = true diff --git a/src/plugins/value/domains/unit_domain.mli b/src/plugins/value/domains/unit_domain.mli index 03a18359466383b2b457973f30e5d872e498228f..e1ed4495741e0e69942ef91292998f274f08b9c9 100644 --- a/src/plugins/value/domains/unit_domain.mli +++ b/src/plugins/value/domains/unit_domain.mli @@ -23,7 +23,7 @@ module Make (Value: Abstract_value.S) (Loc: Abstract_location.S) - : Abstract_domain.Internal with type state = unit + : Abstract.Domain.Internal with type state = unit and type value = Value.t and type location = Loc.location diff --git a/src/plugins/value/engine/abstractions.ml b/src/plugins/value/engine/abstractions.ml index 256fe3fd89b4c89ca13976f788b4c4ecccde0aca..5360df332a1ad973cdeed1d0a09c8a6c7372fc9e 100644 --- a/src/plugins/value/engine/abstractions.ml +++ b/src/plugins/value/engine/abstractions.ml @@ -79,14 +79,14 @@ let legacy_config = { } module type Value = sig - include Abstract_value.External + include Abstract.Value.External val reduce : t -> t end module type S = sig module Val : Value - module Loc : Abstract_location.External with type value = Val.t - module Dom : Abstract_domain.External with type value = Val.t + module Loc : Abstract.Location.External with type value = Val.t + module Dom : Abstract.Domain.External with type value = Val.t and type location = Loc.location end @@ -103,13 +103,28 @@ end (* -------------------------------------------------------------------------- *) module type V = sig - include Abstract_value.External - val structure : t Abstract_value.structure + include Abstract.Value.External + val structure : t Abstract.Value.structure end -module CVal = struct +module Internal_CVal = struct include Main_values.CVal - include Structure.Open (Structure.Key_Value) (Main_values.CVal) + let structure = Abstract.Value.Leaf key +end + +module CVal = struct + include Internal_CVal + include Structure.Open (Structure.Key_Value) (Internal_CVal) +end + +module Internal_PLoc = struct + include Main_locations.PLoc + let structure = Abstract.Location.Leaf key +end + +module Internal_Cvalue_Domain = struct + include Cvalue_domain.State + let structure = Abstract.Domain.Leaf key end let has_apron config = @@ -122,18 +137,20 @@ let has_apron config = abstractions (if they are enabled). Do not display the intervals in the GUI in this case. *) let add_apron_value config value = - let module Left = ((val value: Abstract_value.Internal)) in + let module Left = ((val value: Abstract.Value.Internal)) in let module V = struct include Value_product.Make (Left) (Main_values.Interval) let pretty_typ = if config.cvalue then fun fmt typ (left, _right) -> Left.pretty_typ fmt typ left else pretty_typ + let structure = + Abstract.Value.(Node (Left.structure, Leaf Main_values.Interval.key)) end in - (module V: Abstract_value.Internal) + (module V: Abstract.Value.Internal) let open_value_abstraction value = - let module Value = (val value : Abstract_value.Internal) in + let module Value = (val value : Abstract.Value.Internal) in (module struct include Value include Structure.Open (Structure.Key_Value) (Value) @@ -142,14 +159,19 @@ let open_value_abstraction value = let build_value config = let value = if config.bitwise - then (module Offsm_value.CvalueOffsm : Abstract_value.Internal) - else (module Main_values.CVal : Abstract_value.Internal) + then (module Offsm_value.CvalueOffsm : Abstract.Value.Internal) + else (module Internal_CVal : Abstract.Value.Internal) in let value = if config.signs then - let module V = Value_product.Make ((val value)) (Sign_value) in - (module V: Abstract_value.Internal) + let module Value = (val value) in + let module V = struct + include Value_product.Make (Value) (Sign_value) + let structure = + Abstract.Value.(Node (Value.structure, Leaf Sign_value.key)) + end in + (module V: Abstract.Value.Internal) else value in let value = @@ -166,7 +188,7 @@ let build_value config = (* Builds a module conversion from a generic external value to a key. *) module Convert - (Value : Abstract_value.External) + (Value : Abstract.Value.External) (K : sig type v val key : v Abstract_value.key end) = struct type extended_value = Value.t @@ -194,9 +216,9 @@ end (* Abstractions needed for the analysis: value, location and domain. *) module type Abstract = sig module Val : V - module Loc : Abstract_location.Internal with type value = Val.t + module Loc : Abstract.Location.Internal with type value = Val.t and type location = Precise_locs.precise_location - module Dom : Abstract_domain.Internal with type value = Val.t + module Dom : Abstract.Domain.Internal with type value = Val.t and type location = Loc.location end @@ -205,13 +227,13 @@ let default_root_abstraction config = then (module struct module Val = CVal - module Loc = Main_locations.PLoc - module Dom = Cvalue_domain.State + module Loc = Internal_PLoc + module Dom = Internal_Cvalue_Domain end : Abstract) else (module struct module Val = CVal - module Loc = Main_locations.PLoc + module Loc = Internal_PLoc module Dom = Unit_domain.Make (Val) (Loc) end : Abstract) @@ -219,20 +241,27 @@ let build_root_abstraction config value = let module Val = (val value : V) in let module K = struct type v = Cvalue.V.t - let key = Main_values.cvalue_key + let key = Main_values.CVal.key end in let module Conv = Convert (Val) (K) in + let module Loc = struct + include Location_lift.Make (Main_locations.PLoc) (Conv) + let structure = Abstract.Location.Leaf Internal_PLoc.key + end in if config.cvalue then (module struct module Val = Val - module Loc = Location_lift.Make (Main_locations.PLoc) (Conv) - module Dom = Domain_lift.Make (Cvalue_domain.State) (Conv) + module Loc = Loc + module Dom = struct + include Domain_lift.Make (Cvalue_domain.State) (Conv) + let structure = Abstract.Domain.Leaf Internal_Cvalue_Domain.key + end end : Abstract) else (module struct module Val = Val - module Loc = Location_lift.Make (Main_locations.PLoc) (Conv) + module Loc = Loc module Dom = Unit_domain.Make (Val) (Loc) end : Abstract) @@ -242,17 +271,22 @@ let build_root_abstraction config value = (* -------------------------------------------------------------------------- *) let add_apron_domain abstract apron = - let module Abstract = (val abstract: Abstract) in + let module Acc = (val abstract: Abstract) in let module K = struct type v = Main_values.Interval.t - let key = Main_values.interval_key + let key = Main_values.Interval.key end in - let module Conv = Convert (Abstract.Val) (K) in - let module Apron = Domain_lift.Make ((val apron : Apron_domain.S)) (Conv) in + let module Conv = Convert (Acc.Val) (K) in + let module Apron = (val apron : Apron_domain.S) in + let structure = Abstract.Domain.Leaf Apron.key in + let module Apron = Domain_lift.Make (Apron) (Conv) in (module struct - module Val = Abstract.Val - module Loc = Abstract.Loc - module Dom = Domain_product.Make (Abstract.Val) (Abstract.Dom) (Apron) + module Val = Acc.Val + module Loc = Acc.Loc + module Dom = struct + include Domain_product.Make (Acc.Val) (Acc.Dom) (Apron) + let structure = Abstract.Domain.(Node (Acc.Dom.structure, structure)) + end end : Abstract) let dkey_experimental = Value_parameters.register_category "experimental-ok" @@ -273,32 +307,37 @@ let add_apron_domain abstractions apron = module CvalueEquality = Equality_domain.Make (CVal) -let add_generic_equalities (module Abstract : Abstract) = - let module EqDom = Equality_domain.Make (Abstract.Val) in - let module Dom = Domain_product.Make (Abstract.Val) (Abstract.Dom) (EqDom) in +let add_generic_equalities (module Acc : Abstract) = + let module EqDom = Equality_domain.Make (Acc.Val) in + let module Dom = struct + include Domain_product.Make (Acc.Val) (Acc.Dom) (EqDom) + let structure = Abstract.Domain.(Node (Acc.Dom.structure, Leaf EqDom.key)) + end in (module struct - module Val = Abstract.Val - module Loc = Abstract.Loc + module Val = Acc.Val + module Loc = Acc.Loc module Dom = Dom end : Abstract) -let add_equalities (type v) (module Abstract : Abstract with type Val.t = v) = - match Abstract.Val.structure with +let add_equalities (type v) (module Acc : Abstract with type Val.t = v) = + match Acc.Val.structure with | Structure.Key_Value.Leaf key -> begin - match Structure.Key_Value.eq_type key Main_values.cvalue_key with - | None -> add_generic_equalities (module Abstract) + match Structure.Key_Value.eq_type key Main_values.CVal.key with + | None -> add_generic_equalities (module Acc) | Some Structure.Eq -> - let module Dom = - Domain_product.Make (Abstract.Val) (Abstract.Dom) (CvalueEquality) - in + let module Dom = struct + include Domain_product.Make (Acc.Val) (Acc.Dom) (CvalueEquality) + let structure = + Abstract.Domain.(Node (Acc.Dom.structure, Leaf CvalueEquality.key)) + end in (module struct - module Val = Abstract.Val - module Loc = Abstract.Loc + module Val = Acc.Val + module Loc = Acc.Loc module Dom = Dom end : Abstract) end - | _ -> add_generic_equalities (module Abstract) + | _ -> add_generic_equalities (module Acc) (* -------------------------------------------------------------------------- *) @@ -306,17 +345,21 @@ let add_equalities (type v) (module Abstract : Abstract with type Val.t = v) = (* -------------------------------------------------------------------------- *) let add_offsm abstract = - let module Abstract = (val abstract : Abstract) in + let module Acc = (val abstract : Abstract) in let module K = struct type v = Offsm_value.offsm_or_top - let key = Offsm_value.offsm_key + let key = Offsm_value.Offsm.key end in - let module Conv = Convert (Abstract.Val) (K) in + let module Conv = Convert (Acc.Val) (K) in let module Offsm = Domain_lift.Make (Offsm_domain.D) (Conv) in - let module Dom = Domain_product.Make (Abstract.Val) (Abstract.Dom) (Offsm) in + let module Dom = struct + include Domain_product.Make (Acc.Val) (Acc.Dom) (Offsm) + let structure = + Abstract.Domain.(Node (Acc.Dom.structure, Leaf Offsm_domain.D.key)) + end in (module struct - module Val = Abstract.Val - module Loc = Abstract.Loc + module Val = Acc.Val + module Loc = Acc.Loc module Dom = Dom end : Abstract) @@ -324,23 +367,27 @@ let add_offsm abstract = (* Domains on standard locations and values *) (* -------------------------------------------------------------------------- *) -module type Standard_abstraction = Abstract_domain.Internal +module type Standard_abstraction = Abstract_domain.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location let add_standard_domain d abstract = - let module Abstract = (val abstract : Abstract) in + let module Acc = (val abstract : Abstract) in let module K = struct type v = Cvalue.V.t - let key = Main_values.cvalue_key + let key = Main_values.CVal.key end in - let module Conv = Convert (Abstract.Val) (K) in + let module Conv = Convert (Acc.Val) (K) in let module D = (val d: Standard_abstraction) in let module LD = Domain_lift.Make (D) (Conv) in - let module Dom = Domain_product.Make (Abstract.Val)(Abstract.Dom)(LD) in + let module Dom = struct + include Domain_product.Make (Acc.Val)(Acc.Dom)(LD) + let structure = + Abstract.Domain.(Node (Acc.Dom.structure, Leaf D.key)) + end in (module struct - module Val = Abstract.Val - module Loc = Abstract.Loc + module Val = Acc.Val + module Loc = Acc.Loc module Dom = Dom end : Abstract) @@ -381,17 +428,21 @@ let add_inout = (* -------------------------------------------------------------------------- *) let add_signs abstract = - let module Abstract = (val abstract : Abstract) in + let module Acc = (val abstract : Abstract) in let module K = struct type v = Sign_value.t - let key = Sign_value.sign_key + let key = Sign_value.key end in - let module Conv = Convert (Abstract.Val) (K) in + let module Conv = Convert (Acc.Val) (K) in let module Sign = Domain_lift.Make (Sign_domain) (Conv) in - let module Dom = Domain_product.Make (Abstract.Val) (Abstract.Dom) (Sign) in + let module Dom = struct + include Domain_product.Make (Acc.Val) (Acc.Dom) (Sign) + let structure = + Abstract.Domain.(Node (Acc.Dom.structure, Leaf Sign_domain.key)) + end in (module struct - module Val = Abstract.Val - module Loc = Abstract.Loc + module Val = Acc.Val + module Loc = Acc.Loc module Dom = Dom end : Abstract) @@ -400,18 +451,22 @@ let add_signs abstract = (* -------------------------------------------------------------------------- *) let add_errors abstract = - let module Abstract = (val abstract : Abstract) in + let module Acc = (val abstract : Abstract) in let module K = struct type v = Numerors_domain.value let key = Numerors_domain.value_key end in - let module Conv = Convert (Abstract.Val) (K) in + let module Conv = Convert (Acc.Val) (K) in let module Numerors = (val Numerors_domain.numerors_domain ()) in let module Errors = Domain_lift.Make (Numerors) (Conv) in - let module Dom = Domain_product.Make (Abstract.Val) (Abstract.Dom) (Errors) in + let module Dom = struct + include Domain_product.Make (Acc.Val) (Acc.Dom) (Errors) + let structure = + Abstract.Domain.(Node (Acc.Dom.structure, Leaf Numerors.key)) + end in (module struct - module Val = Abstract.Val - module Loc = Abstract.Loc + module Val = Acc.Val + module Loc = Acc.Loc module Dom = Dom end : Abstract) @@ -439,7 +494,7 @@ let build_abstractions config = let abstractions = match V.structure with | Structure.Key_Value.Leaf key - when Structure.Key_Value.equal key Main_values.cvalue_key -> + when Structure.Key_Value.equal key Main_values.CVal.key -> default_root_abstraction config | _ -> build_root_abstraction config value in @@ -519,7 +574,7 @@ let build_abstractions config = (* Add the reduce function to the value module. *) -module Reduce (Value : Abstract_value.External) = struct +module Reduce (Value : Abstract.Value.External) = struct include Value @@ -528,11 +583,11 @@ module Reduce (Value : Abstract_value.External) = struct other. If the Cvalue is not a scalar do nothing, because we do not currently use Apron for pointer offsets. *) let reduce_apron_itv = - match Value.get Main_values.interval_key, Value.get Main_values.cvalue_key with + match Value.get Main_values.Interval.key, Value.get Main_values.CVal.key with | Some get_interval, Some get_cvalue -> begin - let set_cvalue = Value.set Main_values.cvalue_key in - let set_interval = Value.set Main_values.interval_key in + let set_cvalue = Value.set Main_values.CVal.key in + let set_interval = Value.set Main_values.Interval.key in fun t -> match get_interval t with | None -> begin diff --git a/src/plugins/value/engine/abstractions.mli b/src/plugins/value/engine/abstractions.mli index 996f0aaa0392ad6ab229d4cd1f1429419530bd06..15837823e65ac26836451b1a26c528b025cde2f5 100644 --- a/src/plugins/value/engine/abstractions.mli +++ b/src/plugins/value/engine/abstractions.mli @@ -53,7 +53,7 @@ val configure : unit -> config module type Value = sig - include Abstract_value.External + include Abstract.Value.External val reduce : t -> t end @@ -61,8 +61,8 @@ end abstractions.*) module type S = sig module Val : Value - module Loc : Abstract_location.External with type value = Val.t - module Dom : Abstract_domain.External with type value = Val.t + module Loc : Abstract.Location.External with type value = Val.t + module Dom : Abstract.Domain.External with type value = Val.t and type location = Loc.location end @@ -78,7 +78,7 @@ module type Eva = sig end (** Type of abstractions that use the builtin types for values and locations *) -module type Standard_abstraction = Abstract_domain.Internal +module type Standard_abstraction = Abstract_domain.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location diff --git a/src/plugins/value/engine/compute_functions.ml b/src/plugins/value/engine/compute_functions.ml index d265352833e4dbbf7b2d88c7ed8483849670c57d..4440415631b5dd90793189134a401c3e655e9dfa 100644 --- a/src/plugins/value/engine/compute_functions.ml +++ b/src/plugins/value/engine/compute_functions.ml @@ -149,17 +149,17 @@ module Make (Abstract: Abstractions.Eva) = struct let initial_state = Init.initial_state let get_cvalue = - match Abstract.Dom.get Cvalue_domain.key with + match Abstract.Dom.get Cvalue_domain.State.key with | None -> fun _ -> Cvalue.Model.top - | Some get -> fun state -> get state + | Some get -> fun state -> Cvalue_domain.project (get state) let get_cval = - match Abstract.Val.get Main_values.cvalue_key with + match Abstract.Val.get Main_values.CVal.key with | None -> fun _ -> assert false | Some get -> fun value -> get value let get_ploc = - match Abstract.Loc.get Main_locations.ploc_key with + match Abstract.Loc.get Main_locations.PLoc.key with | None -> fun _ -> assert false | Some get -> fun location -> get location @@ -312,17 +312,16 @@ module Make (Abstract: Abstractions.Eva) = struct let cvalue_states, cacheable = Builtins.apply_builtin builtin cvalue_call cvalue_state in - let insert (cvalue_state, clobbered_set) = - Abstract.Dom.set Locals_scoping.key clobbered_set - (Abstract.Dom.set Cvalue_domain.key cvalue_state final_state) + let insert cvalue_state = + Abstract.Dom.set Cvalue_domain.State.key cvalue_state final_state in let states = Bottom.bot_of_list (List.map insert cvalue_states) in Transfer.{states; cacheable; builtin=true} let compute_call = - if Abstract.Dom.mem Cvalue_domain.key - && Abstract.Val.mem Main_values.cvalue_key - && Abstract.Loc.mem Main_locations.ploc_key + if Abstract.Dom.mem Cvalue_domain.State.key + && Abstract.Val.mem Main_values.CVal.key + && Abstract.Loc.mem Main_locations.PLoc.key then compute_call_or_builtin else compute_and_cache_call diff --git a/src/plugins/value/engine/evaluation.ml b/src/plugins/value/engine/evaluation.ml index cc4018b105ace85d2ef41e338aede20e702b64bf..b56d00620330f489f0e440f296aa0e575f5b6465 100644 --- a/src/plugins/value/engine/evaluation.ml +++ b/src/plugins/value/engine/evaluation.ml @@ -263,7 +263,7 @@ let indeterminate_copy lval result alarms = module type Value = sig - include Abstract_value.External + include Abstract.Value.External val reduce : t -> t end diff --git a/src/plugins/value/engine/evaluation.mli b/src/plugins/value/engine/evaluation.mli index ad8886669f22c25f17b0a08d404ba0c81efd8cec..f7febc17e4242c9d2b6f01189995ec86afcdfecc 100644 --- a/src/plugins/value/engine/evaluation.mli +++ b/src/plugins/value/engine/evaluation.mli @@ -104,7 +104,7 @@ module type S = sig end module type Value = sig - include Abstract_value.External + include Abstract.Value.External (** Inter-reduction of values. Useful when the value module is a reduced product of several abstraction. diff --git a/src/plugins/value/engine/initialization.ml b/src/plugins/value/engine/initialization.ml index 317446467c2dcd3b4e657f30019dc3407b098146..6f15c07d5d656a644e39895b095726493790376a 100644 --- a/src/plugins/value/engine/initialization.ml +++ b/src/plugins/value/engine/initialization.ml @@ -80,7 +80,7 @@ let (>>>) t f = match t with let counter = ref 0 module Make - (Domain: Abstract_domain.External) + (Domain: Abstract.Domain.External) (Eva: Evaluation.S with type state = Domain.state and type loc = Domain.location) (Transfer: Transfer_stmt.S with type state = Domain.t) @@ -270,7 +270,7 @@ module Make (* Use the values supplied in [actuals] for the formals of [kf], and bind them in [state] *) let add_supplied_main_formals kf actuals state = - match Domain.get Cvalue_domain.key with + match Domain.get Cvalue_domain.State.key with | None -> Value_parameters.abort "Function Db.Value.fun_set_args cannot be used \ without the Cvalue domain" @@ -278,7 +278,7 @@ module Make let formals = Kernel_function.get_formals kf in if (List.length formals) <> List.length actuals then raise Db.Value.Incorrect_number_of_arguments; - let cvalue_state = get_cvalue state in + let cvalue_state = Cvalue_domain.project (get_cvalue state) in let add_actual state actual formal = let actual = Eval_op.offsetmap_of_v ~typ:formal.vtype actual in Cvalue.Model.add_base (Base.of_varinfo formal) actual state @@ -286,8 +286,8 @@ module Make let cvalue_state = List.fold_left2 add_actual cvalue_state actuals formals in - let set_domain = Domain.set Cvalue_domain.key in - set_domain cvalue_state state + let set_domain = Domain.set Cvalue_domain.State.key in + set_domain (Cvalue_domain.inject cvalue_state) state let add_main_formals kf state = match Db.Value.fun_get_args () with @@ -354,7 +354,9 @@ module Make let supplied_state () = let cvalue_state = Db.Value.globals_state () in if Cvalue.Model.is_reachable cvalue_state - then `Value (Domain.set Cvalue_domain.key cvalue_state Domain.top) + then + let cvalue_state = Cvalue_domain.inject cvalue_state in + `Value (Domain.set Cvalue_domain.State.key cvalue_state Domain.top) else `Bottom let initial_state ~lib_entry = diff --git a/src/plugins/value/engine/initialization.mli b/src/plugins/value/engine/initialization.mli index d3bf03c164d12c1a524f8efffead3446eb2b17eb..f87a4799a8dabf85382536a3faf4beb8eb9deab9 100644 --- a/src/plugins/value/engine/initialization.mli +++ b/src/plugins/value/engine/initialization.mli @@ -44,7 +44,7 @@ module type S = sig end module Make - (Domain: Abstract_domain.External) + (Domain: Abstract.Domain.External) (Eva: Evaluation.S with type state = Domain.state and type loc = Domain.location) (Transfer: Transfer_stmt.S with type state = Domain.t) diff --git a/src/plugins/value/engine/iterator.ml b/src/plugins/value/engine/iterator.ml index 541d61dd21f62783f1efeb762824b51b4bb54b27..0e83fb39280cd62436229a5d74a6b8cd5ff5def8 100644 --- a/src/plugins/value/engine/iterator.ml +++ b/src/plugins/value/engine/iterator.ml @@ -433,10 +433,10 @@ module Make_Dataflow edge_info.fireable <- true; flow - let get_cvalue = Domain.get Cvalue_domain.key + let get_cvalue = Domain.get Cvalue_domain.State.key let gather_cvalues states = match get_cvalue with - | Some get -> List.map get states + | Some get -> List.map (fun s -> Cvalue_domain.project (get s)) states | None -> [] let call_statement_callbacks (stmt : stmt) (f : flow) : unit = diff --git a/src/plugins/value/engine/partition.ml b/src/plugins/value/engine/partition.ml index 68686f72d14cc2cfa28af182e0714db28e980b5b..644e3bf20b5a617f34df40a686b12dadabab3bf4 100644 --- a/src/plugins/value/engine/partition.ml +++ b/src/plugins/value/engine/partition.ml @@ -245,7 +245,7 @@ struct all states" in (* Get the cvalue *) - let cvalue = match Abstract.Val.get Main_values.cvalue_key with + let cvalue = match Abstract.Val.get Main_values.CVal.key with | Some get_cvalue -> get_cvalue value | None -> fail ~exp "partitioning is disabled when the CValue domain is \ not active" @@ -325,7 +325,7 @@ struct (* --- Applying partitioning actions onto flows --------------------------- *) - let stamp_by_value = match Abstract.Val.get Main_values.cvalue_key with + let stamp_by_value = match Abstract.Val.get Main_values.CVal.key with | None -> fun _ _ _ -> None | Some get -> fun expr expected_values state -> let typ = Cil.typeOf expr in diff --git a/src/plugins/value/engine/partitioning_index.ml b/src/plugins/value/engine/partitioning_index.ml index 08a2f449cf02a90603131b2b7dca16623c10df5e..af4202973238a17d341109ddadd4f1ede3fe9319 100644 --- a/src/plugins/value/engine/partitioning_index.ml +++ b/src/plugins/value/engine/partitioning_index.ml @@ -23,7 +23,8 @@ module type Domain = sig include Abstract_domain.Lattice include Datatype.S_with_collections with type t = state - include Abstract_domain.Interface with type t := state + include Abstract.Interface with type t := state + and type 'a key := 'a Abstract_domain.key end (** Partition of the abstract states, computed for each node by the @@ -45,12 +46,12 @@ module Make (* Optimizations relying on specific features of the cvalue domain. *) - let distinct_subpart = match Domain.get Cvalue_domain.key with + let distinct_subpart = match Domain.get Cvalue_domain.State.key with | None -> fun _ _ -> None | Some get -> fun s1 s2 -> Cvalue_domain.distinct_subpart (get s1) (get s2) - let find_subpart = match Domain.get Cvalue_domain.key with + let find_subpart = match Domain.get Cvalue_domain.State.key with | None -> fun _ _ -> None | Some get -> fun state prefix -> Cvalue_domain.find_subpart (get state) prefix diff --git a/src/plugins/value/engine/partitioning_index.mli b/src/plugins/value/engine/partitioning_index.mli index b4488a2eef755c6056994295834de7d54afba023..9a72e4b44bb7cde362196aebea23713899381e18 100644 --- a/src/plugins/value/engine/partitioning_index.mli +++ b/src/plugins/value/engine/partitioning_index.mli @@ -33,7 +33,8 @@ module type Domain = sig include Abstract_domain.Lattice include Datatype.S_with_collections with type t = state - include Abstract_domain.Interface with type t := state + include Abstract.Interface with type t := state + and type 'a key := 'a Abstract_domain.key end module Make (Domain: Domain) : sig diff --git a/src/plugins/value/engine/subdivided_evaluation.ml b/src/plugins/value/engine/subdivided_evaluation.ml index ae1efe494c8c2dd823b6c5a7dd6b428795ecf024..3d0e928ef9f2da8cd8a22afc259eef4c4c6a90e3 100644 --- a/src/plugins/value/engine/subdivided_evaluation.ml +++ b/src/plugins/value/engine/subdivided_evaluation.ml @@ -368,7 +368,7 @@ module type Forward_Evaluation = sig end module Make - (Value : Abstract_value.External) + (Value : Abstract.Value.External) (Loc : Abstract_location.S with type value = Value.t) (Valuation: Valuation with type value = Value.t and type loc = Loc.location) @@ -379,15 +379,15 @@ module Make (* Values are converted to {!Cvalue.V.t}, because those are currently the only values on which we can split. *) - let get_cval = match Value.get Main_values.cvalue_key with + let get_cval = match Value.get Main_values.CVal.key with | Some get -> get | None -> fun _ -> Cvalue.V.top let set_cval = - let set = Value.set Main_values.cvalue_key in + let set = Value.set Main_values.CVal.key in fun cval v -> set cval v - let activated = Value.mem Main_values.cvalue_key + let activated = Value.mem Main_values.CVal.key module Clear = Clear_Valuation (Valuation) diff --git a/src/plugins/value/engine/subdivided_evaluation.mli b/src/plugins/value/engine/subdivided_evaluation.mli index 745624c457517ac366c4f7734bd7960c9bb6d3d7..71d582bb70d8a4e1f6bda7d6d77b88051d08f994 100644 --- a/src/plugins/value/engine/subdivided_evaluation.mli +++ b/src/plugins/value/engine/subdivided_evaluation.mli @@ -36,7 +36,7 @@ module type Forward_Evaluation = sig end module Make - (Value : Abstract_value.External) + (Value : Abstract.Value.External) (Loc: Abstract_location.S with type value = Value.t) (Valuation: Eval.Valuation with type value = Value.t and type loc = Loc.location) diff --git a/src/plugins/value/engine/transfer_specification.ml b/src/plugins/value/engine/transfer_specification.ml index d5438b227de994181748fcdadfd7c43f3a49b05b..69171aaeec78721bd2c156951fea6e5d791df366 100644 --- a/src/plugins/value/engine/transfer_specification.ml +++ b/src/plugins/value/engine/transfer_specification.ml @@ -227,14 +227,14 @@ module Make (* Extraction of the precise location and of the cvalue domain: needed to evaluate the location of an assigns clause. *) - let get_ploc = match Location.get Main_locations.ploc_key with + let get_ploc = match Location.get Main_locations.PLoc.key with | None -> fun _ -> Main_locations.PLoc.top | Some get -> get - let set_ploc = Location.set Main_locations.ploc_key + let set_ploc = Location.set Main_locations.PLoc.key let set_location loc = set_ploc (Main_locations.PLoc.make loc) - let get_cvalue_state = match Domain.get Cvalue_domain.key with + let get_cvalue_state = match Domain.get Cvalue_domain.State.key with | None -> fun _ -> Cvalue.Model.top - | Some get -> get + | Some get -> fun s -> Cvalue_domain.project (get s) let make_env state = Eval_terms.env_assigns (get_cvalue_state state) diff --git a/src/plugins/value/engine/transfer_stmt.ml b/src/plugins/value/engine/transfer_stmt.ml index e7be6f8f5827d5e2172721c25c0a7529cc7e321a..c0f99adcbda13fd6af6563f097ae04be9534acee 100644 --- a/src/plugins/value/engine/transfer_stmt.ml +++ b/src/plugins/value/engine/transfer_stmt.ml @@ -318,7 +318,7 @@ module Make (Abstract: Abstractions.Eva) = struct (* ------------------- Retro propagation on formals ----------------------- *) - let get_precise_location = Location.get Main_locations.ploc_key + let get_precise_location = Location.get Main_locations.PLoc.key (* [is_safe_argument valuation expr] is true iff the expression [expr] could not have been written during the last call. @@ -559,9 +559,9 @@ module Make (Abstract: Abstractions.Eva) = struct (* ----------------- show_each and dump_each directives ------------------- *) - let extract_cvalue = match Domain.get Cvalue_domain.key with + let extract_cvalue = match Domain.get Cvalue_domain.State.key with | None -> fun _ -> Cvalue.Model.top - | Some get -> get + | Some get -> fun s -> Cvalue_domain.project (get s) (* The product of domains formats the printing of each leaf domains, by checking their log_category and adding their name before the dump. If the @@ -609,7 +609,7 @@ module Make (Abstract: Abstractions.Eva) = struct (* For non scalar expressions, prints the offsetmap of the cvalue domain. *) let show_offsm = - match Domain.get Cvalue_domain.key, Location.get Main_locations.ploc_key with + match Domain.get Cvalue_domain.State.key, Location.get Main_locations.PLoc.key with | None, _ | _, None -> fun fmt _ _ -> Format.fprintf fmt "%s" (Unicode.top_string ()) | Some get_cvalue, Some get_ploc -> @@ -622,7 +622,7 @@ module Make (Abstract: Abstractions.Eva) = struct fst (Eval.lvaluate ~for_writing:false state lval) >>- fun (_, loc, _) -> let ploc = get_ploc loc - and cvalue_state = get_cvalue state in + and cvalue_state = Cvalue_domain.project (get_cvalue state) in Eval_op.offsetmap_of_loc ploc cvalue_state in let typ = Cil.typeOf expr in @@ -634,7 +634,7 @@ module Make (Abstract: Abstractions.Eva) = struct (* For scalar expressions, prints the cvalue component of their values. *) let show_value = - match Value.get Main_values.cvalue_key with + match Value.get Main_values.CVal.key with | None -> fun fmt _ _ -> Format.fprintf fmt "%s" (Unicode.top_string ()) | Some get_cval -> fun fmt expr state -> diff --git a/src/plugins/value/gui_files/gui_eval.ml b/src/plugins/value/gui_files/gui_eval.ml index 108079350d90481f0a0ec71c200f2a62b0d93443..2c64ede8741331662b1b3085078c4ba5e77364af 100644 --- a/src/plugins/value/gui_files/gui_eval.ml +++ b/src/plugins/value/gui_files/gui_eval.ml @@ -144,12 +144,12 @@ module Make (X: Analysis.S) = struct module Analysis = X let get_cvalue_state = - match X.Dom.get Cvalue_domain.key with + match X.Dom.get Cvalue_domain.State.key with | None -> fun _ -> Cvalue.Model.top - | Some get -> fun state -> get state + | Some get -> fun state -> Cvalue_domain.project (get state) let get_precise_loc = - match X.Loc.get Main_locations.ploc_key with + match X.Loc.get Main_locations.PLoc.key with | None -> fun _ -> Precise_locs.loc_top | Some get -> fun loc -> get loc diff --git a/src/plugins/value/gui_files/gui_types.ml b/src/plugins/value/gui_files/gui_types.ml index 683fa0398606aed22d2fafb21e85f26d2de82070..f4fad0001bcf153f14c432216195984d1da38804 100644 --- a/src/plugins/value/gui_files/gui_types.ml +++ b/src/plugins/value/gui_files/gui_types.ml @@ -167,8 +167,8 @@ module Make (V: Abstractions.Value) = struct | GA_After r1, GA_After r2 -> equal_gui_res r1 r2 | (GA_After _ | GA_NA | GA_Unchanged | GA_Bottom), _ -> false - let get_cvalue = V.get Main_values.cvalue_key - let from_cvalue v = V.set Main_values.cvalue_key v V.top + let get_cvalue = V.get Main_values.CVal.key + let from_cvalue v = V.set Main_values.CVal.key v V.top let var_of_base base acc = try diff --git a/src/plugins/value/register.ml b/src/plugins/value/register.ml index b7198f212195417767e50c26497c272c0026b8c5..d3103749d06ab0fc0e6819ac4ff21ffb6392ead5 100644 --- a/src/plugins/value/register.ml +++ b/src/plugins/value/register.ml @@ -169,9 +169,14 @@ let () = open Eval -module Val = struct +module CVal = struct include Main_values.CVal - include Structure.Open (Structure.Key_Value) (Main_values.CVal) + let structure = Abstract.Value.Leaf key +end + +module Val = struct + include CVal + include Structure.Open (Structure.Key_Value) (CVal) let reduce t = t end diff --git a/src/plugins/value/utils/abstract.ml b/src/plugins/value/utils/abstract.ml new file mode 100644 index 0000000000000000000000000000000000000000..54cf436f968546860044cf4e9c28629428996dff --- /dev/null +++ b/src/plugins/value/utils/abstract.ml @@ -0,0 +1,75 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +(** External interface of an abstraction, built by {!Structure.Open}. *) +module type Interface = sig + type t + type 'a key + val mem : 'a key -> bool + val get : 'a key -> (t -> 'a) option + val set : 'a key -> 'a -> t -> t +end + +module Value = struct + include Structure.Key_Value + + module type Internal = sig + include Abstract_value.S + val structure: t structure + end + + module type External = sig + include Internal + include Structure.External with type t := t + and type 'a key := 'a key + end +end + +module Location = struct + include Structure.Key_Location + + module type Internal = sig + include Abstract_location.S + val structure: location structure + end + + module type External = sig + include Internal + include Structure.External with type t := location + and type 'a key := 'a key + end +end + +module Domain = struct + include Structure.Key_Domain + + module type Internal = sig + include Abstract_domain.Internal + val structure: t structure + end + + module type External = sig + include Internal + include Structure.External with type t := t + and type 'a key := 'a key + end +end diff --git a/src/plugins/value/utils/abstract.mli b/src/plugins/value/utils/abstract.mli new file mode 100644 index 0000000000000000000000000000000000000000..ad5037857fb279840fcab7c6a6b9d6d5e8a97f9b --- /dev/null +++ b/src/plugins/value/utils/abstract.mli @@ -0,0 +1,113 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2019 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +(** Internal and External signature of abstractions used in the Eva engine. *) + +(** Internal modules contains a [structure] value that describes the internal + structure of the abstraction. This structure is used to automatically + generate efficient accessors from a generic compound abstraction to specific + leaf abstractions. *) + +(** External modules export direct accessors to their leaf components. + When a generic abstraction is a product of several specific abstractions, + they allow interacting with each leaf abstraction identified by a key. + Note that their behavior is undefined if an abstraction contains + several times the same leaf module. *) + +(** External interface of an abstraction, built by {!Structure.Open}. *) +module type Interface = sig + type t + type 'a key + + (** Tests whether a key belongs to the module. *) + val mem : 'a key -> bool + + (** For a key of type [k key]: + - if the values of type [t] contain a subpart of type [k] from a module + identified by the key, then [get key] returns an accessor for it. + - otherwise, [get key] returns None. *) + val get : 'a key -> (t -> 'a) option + + (** For a key of type [k key]: + - if the values of type [t] contain a subpart of type [k] from a module + identified by the key, then [set key v t] returns the value [t] in which + this subpart has been replaced by [v]. + - otherwise, [set key _] is the identity function. *) + val set : 'a key -> 'a -> t -> t +end + +(** Key and structure for abstract values. + See {structure.mli} for more details. *) +module Value : sig + include Structure.Shape + with type 'a key = 'a Structure.Key_Value.key + and type 'a structure = 'a Structure.Key_Value.structure + + module type Internal = sig + include Abstract_value.S + val structure: t structure + end + + module type External = sig + include Internal + include Interface with type t := t + and type 'a key := 'a key + end +end + +(** Key and structure for abstract locations. + See {structure.mli} for more details. *) +module Location : sig + include Structure.Shape + with type 'a key = 'a Structure.Key_Location.key + and type 'a structure = 'a Structure.Key_Location.structure + + module type Internal = sig + include Abstract_location.S + val structure: location structure + end + + module type External = sig + include Internal + include Interface with type t := location + and type 'a key := 'a key + end +end + +(** Key and structure for abstract domains. + See {structure.mli} for more details. *) +module Domain : sig + include Structure.Shape + with type 'a key = 'a Structure.Key_Domain.key + and type 'a structure = 'a Structure.Key_Domain.structure + + module type Internal = sig + include Abstract_domain.Internal + val structure: t structure + end + + module type External = sig + include Internal + include Interface with type t := t + and type 'a key := 'a key + end +end diff --git a/src/plugins/value/values/abstract_location.mli b/src/plugins/value/values/abstract_location.mli index 419908727596f04383abf22f2f13354e1a835945..6242ecc18d1f1b3df5d183dbccc6b59aeeb41cf2 100644 --- a/src/plugins/value/values/abstract_location.mli +++ b/src/plugins/value/values/abstract_location.mli @@ -119,21 +119,14 @@ module type S = sig typ -> index:value -> remaining:offset -> offset -> (value * offset) or_bottom end -(** Key and structure for locations. See {structure.mli}, - and {domain.mli} where the mechanism is explained in detail.*) +type 'loc key = 'loc Structure.Key_Location.key -type 'a key = 'a Structure.Key_Location.key -type 'a structure = 'a Structure.Key_Location.structure - -module type Internal = sig +(** Signature for a leaf module of abstract locations. *) +module type Leaf = sig include S - val structure : location structure -end -module type External = sig - include S - include Structure.External with type t := location - and type 'a key := 'a key + (** The key identifies the module and the type [t] of abstract locations. *) + val key: location key end (* diff --git a/src/plugins/value/values/abstract_value.mli b/src/plugins/value/values/abstract_value.mli index 25fab072de6d37a28cf0644e15e32c0278ae8c2e..c6efd63271876b27d54960adc4f32e5697b3d139 100644 --- a/src/plugins/value/values/abstract_value.mli +++ b/src/plugins/value/values/abstract_value.mli @@ -181,21 +181,14 @@ module type S = sig end -(** Key and structure for values. See {structure.mli}, - and {domain.mli} where the mechanism is explained in detail.*) +type 'v key = 'v Structure.Key_Value.key -type 'a key = 'a Structure.Key_Value.key -type 'a structure = 'a Structure.Key_Value.structure - -module type Internal = sig +(** Signature for a leaf module of abstract values. *) +module type Leaf = sig include S - val structure : t structure -end -module type External = sig - include S - include Structure.External with type t := t - and type 'a key := 'a key + (** The key identifies the module and the type [t] of abstract values. *) + val key: t key end diff --git a/src/plugins/value/values/location_lift.ml b/src/plugins/value/values/location_lift.ml index ce5ae27c8641259ef90652d9d36dffffee6ad2bf..4ae36f3622c5bc5bc304ea335a19104bea4efaf1 100644 --- a/src/plugins/value/values/location_lift.ml +++ b/src/plugins/value/values/location_lift.ml @@ -32,12 +32,12 @@ module type Conversion = sig end module Make - (Loc: Abstract_location.Internal) + (Loc: Abstract_location.S) (Convert : Conversion with type internal_value := Loc.value) = struct (* Import most of [Loc] *) - include (Loc: Abstract_location.Internal + include (Loc: Abstract_location.S with type value := Loc.value (* we are converting this type *) and type location = Loc.location and type offset = Loc.offset) diff --git a/src/plugins/value/values/location_lift.mli b/src/plugins/value/values/location_lift.mli index 1eb2d98d38c1da61d05b0891f7e6f88cda650e87..602fbcee4551820ff7cc505da2f0ff4892dbc75f 100644 --- a/src/plugins/value/values/location_lift.mli +++ b/src/plugins/value/values/location_lift.mli @@ -30,11 +30,11 @@ module type Conversion = sig end module Make - (Loc: Abstract_location.Internal) + (Loc: Abstract_location.S) (Convert : Conversion with type internal_value := Loc.value) - : Abstract_location.Internal with type location = Loc.location - and type offset = Loc.offset - and type value = Convert.extended_value + : Abstract_location.S with type location = Loc.location + and type offset = Loc.offset + and type value = Convert.extended_value (* diff --git a/src/plugins/value/values/main_locations.ml b/src/plugins/value/values/main_locations.ml index f98119eab16be0479dd44dbd92e7c66bb668296d..8722ef3517205bc1e9d53b74c754e44cc6a87292 100644 --- a/src/plugins/value/values/main_locations.ml +++ b/src/plugins/value/values/main_locations.ml @@ -22,8 +22,6 @@ open Cil_types -let ploc_key = Structure.Key_Location.create_key "precise_locs" - module PLoc = struct type value = Cvalue.V.t @@ -32,7 +30,7 @@ module PLoc = struct | Precise of Precise_locs.precise_offset | Imprecise of Cvalue.V.t (* when the offset contains addresses *) - let structure = Structure.Key_Location.Leaf ploc_key + let key = Structure.Key_Location.create_key "precise_locs" let equal_loc = Precise_locs.equal_loc let equal_offset o1 o2 = match o1, o2 with diff --git a/src/plugins/value/values/main_locations.mli b/src/plugins/value/values/main_locations.mli index 28d11c16b762f742bdcc3364c4d01de67d6ca0c3..7701838d407cb735e23a76bd8de2a1f74bdb558a 100644 --- a/src/plugins/value/values/main_locations.mli +++ b/src/plugins/value/values/main_locations.mli @@ -25,7 +25,7 @@ (** Abstract locations built over Precise_locs. *) module PLoc : sig - include Abstract_location.Internal + include Abstract_location.Leaf with type value = Cvalue.V.t and type location = Precise_locs.precise_location @@ -33,10 +33,6 @@ module PLoc : sig end -(** Key for precise locs. *) -val ploc_key : PLoc.location Abstract_location.key - - (* Local Variables: compile-command: "make -C ../../../.." diff --git a/src/plugins/value/values/main_values.ml b/src/plugins/value/values/main_values.ml index f5bec06d977060be6fd796cedaea8bfde736f059..83b93bbfb6321503ef84c4d54421936a7e2cd2b1 100644 --- a/src/plugins/value/values/main_values.ml +++ b/src/plugins/value/values/main_values.ml @@ -22,12 +22,10 @@ open Cil_types -let cvalue_key = Structure.Key_Value.create_key "cvalue" - module CVal = struct include Cvalue.V - let structure = Structure.Key_Value.Leaf cvalue_key + let key = Structure.Key_Value.create_key "cvalue" let zero = Cvalue.V.singleton_zero let one = Cvalue.V.singleton_one @@ -135,12 +133,10 @@ module CVal = struct with Abstract_interp.Error_Top -> `Top, true end -let interval_key = Structure.Key_Value.create_key "interval" - module Interval = struct include Datatype.Option (Ival) - let structure = Structure.Key_Value.Leaf interval_key + let key = Structure.Key_Value.create_key "interval" let pretty_typ _ = pretty diff --git a/src/plugins/value/values/main_values.mli b/src/plugins/value/values/main_values.mli index fd148fcfcc5208e58353e0a847249b4d715a3c14..4923f3182ed2e685eaefa4653bae7a840b9b0fb8 100644 --- a/src/plugins/value/values/main_values.mli +++ b/src/plugins/value/values/main_values.mli @@ -23,17 +23,11 @@ (** Main numeric values of Eva. *) (** Abstract values built over Cvalue.V *) -module CVal : Abstract_value.Internal with type t = Cvalue.V.t - -(** Key for cvalues. *) -val cvalue_key : CVal.t Abstract_value.key +module CVal : Abstract_value.Leaf with type t = Cvalue.V.t (** Dummy interval: no forward nor backward propagations. [None] is top. *) -module Interval : Abstract_value.Internal with type t = Ival.t option - -(** Key for intervals. *) -val interval_key : Interval.t Abstract_value.key +module Interval : Abstract_value.Leaf with type t = Ival.t option (* Local Variables: diff --git a/src/plugins/value/values/numerors/numerors_value.ml b/src/plugins/value/values/numerors/numerors_value.ml index 8fa47dc923f6337a7a09483991e497cb2d08da7f..6ef7042aa6964c78ea5a70bfac37a58a5fb76955 100644 --- a/src/plugins/value/values/numerors/numerors_value.ml +++ b/src/plugins/value/values/numerors/numerors_value.ml @@ -116,8 +116,7 @@ end include Datatype.Make(T) let pretty_debug = pretty let pretty_typ _ = pretty -let error_key = Structure.Key_Value.create_key "numerors_values" -let structure = Structure.Key_Value.Leaf error_key +let key = Structure.Key_Value.create_key "numerors_values" (*----------------------------------------------------------------------------- diff --git a/src/plugins/value/values/numerors/numerors_value.mli b/src/plugins/value/values/numerors/numerors_value.mli index 44da21eca973d30b54965cbce4a673f9ac225036..3c87147b3e30abae9d15aa503bf164147ddaf18c 100644 --- a/src/plugins/value/values/numerors/numerors_value.mli +++ b/src/plugins/value/values/numerors/numerors_value.mli @@ -20,15 +20,13 @@ (* *) (**************************************************************************) -include Abstract_value.Internal +include Abstract_value.Leaf val pretty_debug : t Pretty_utils.formatter (** Reduction of an error value according to a floating-point interval. *) val reduce: Fval.t -> t -> t Eval.or_bottom -val error_key : t Structure.Key_Value.key - val set_absolute_to_top : t -> t val set_relative_to_top : t -> t diff --git a/src/plugins/value/values/offsm_value.ml b/src/plugins/value/values/offsm_value.ml index a447493695dcb04a94297946066499e67a8c077c..2a6bab76fb2ec98089ab153e3c13a1ad57cddf81 100644 --- a/src/plugins/value/values/offsm_value.ml +++ b/src/plugins/value/values/offsm_value.ml @@ -381,12 +381,10 @@ module Datatype_Offsm_or_top = Datatype.Make_with_collections(struct end) -let offsm_key = Structure.Key_Value.create_key "offsetmap_value" - -module Offsm : Abstract_value.Internal with type t = offsm_or_top = struct +module Offsm : Abstract_value.Leaf with type t = offsm_or_top = struct include Datatype_Offsm_or_top - let structure = Structure.Key_Value.Leaf offsm_key + let key = Structure.Key_Value.create_key "offsetmap_value" let pretty_typ typ fmt = function | Top as o -> pretty fmt o @@ -480,10 +478,13 @@ module Offsm : Abstract_value.Internal with type t = offsm_or_top = struct end -module CvalueOffsm : Abstract_value.Internal with type t = V.t * offsm_or_top +module CvalueOffsm : Abstract.Value.Internal with type t = V.t * offsm_or_top = struct include Value_product.Make (Main_values.CVal) (Offsm) + let structure = + Abstract.Value.(Node (Leaf Main_values.CVal.key, Leaf Offsm.key)) + let size typ = Integer.of_int (Cil.bitsSizeOf typ) (* Extract an offsetmap from a pair, by converting the value when needed. *) diff --git a/src/plugins/value/values/offsm_value.mli b/src/plugins/value/values/offsm_value.mli index 088bf7f0843f70bdd215e1389d1c4bcc465f263e..6465583c14eac05255723276ac81be8d94f5cafb 100644 --- a/src/plugins/value/values/offsm_value.mli +++ b/src/plugins/value/values/offsm_value.mli @@ -22,13 +22,10 @@ type offsm_or_top = O of Cvalue.V_Offsetmap.t | Top -val offsm_key : offsm_or_top Structure.Key_Value.key - val cast : old_size: Integer.t -> new_size: Integer.t -> signed: bool -> Cvalue.V_Offsetmap.t -> Cvalue.V_Offsetmap.t +module Offsm : Abstract_value.Leaf with type t = offsm_or_top -module Offsm : Abstract_value.Internal with type t = offsm_or_top - -module CvalueOffsm : Abstract_value.Internal with type t = Cvalue.V.t * offsm_or_top +module CvalueOffsm : Abstract.Value.Internal with type t = Cvalue.V.t * offsm_or_top diff --git a/src/plugins/value/values/sign_value.ml b/src/plugins/value/values/sign_value.ml index 211ce3cd5b2891d14d9a44a6e6f5862aed9eb762..66ebbb989c5bd9fd1fe05f9c2d258e59e66feaff 100644 --- a/src/plugins/value/values/sign_value.ml +++ b/src/plugins/value/values/sign_value.ml @@ -271,5 +271,4 @@ let backward_cast ~src_typ:_ ~dst_typ:_ ~src_val:_ ~dst_val:_ = `Value None (** {2 Misc} *) (* Eva boilerplate, used to retrieve the domain. *) -let sign_key = Structure.Key_Value.create_key "sign_values" -let structure = Structure.Key_Value.Leaf sign_key +let key = Structure.Key_Value.create_key "sign_values" diff --git a/src/plugins/value/values/sign_value.mli b/src/plugins/value/values/sign_value.mli index 9a71c60d69cd2689f9435f505c51952355f3805c..44b761fb982e26370f6bc2f85c71e0618c85150b 100644 --- a/src/plugins/value/values/sign_value.mli +++ b/src/plugins/value/values/sign_value.mli @@ -22,8 +22,6 @@ (** Sign domain: abstraction of integer numerical values by their signs. *) -include Abstract_value.Internal +include Abstract_value.Leaf val pretty_debug: t Pretty_utils.formatter - -val sign_key : t Structure.Key_Value.key diff --git a/src/plugins/value/values/value_product.ml b/src/plugins/value/values/value_product.ml index 131d47bfa680cd438e8146e4de79bcf1a3b99d29..5a088c5283873e658f87f003c5766d010bf1dda8 100644 --- a/src/plugins/value/values/value_product.ml +++ b/src/plugins/value/values/value_product.ml @@ -23,14 +23,12 @@ open Eval module Make - (Left: Abstract_value.Internal) - (Right: Abstract_value.Internal) + (Left: Abstract_value.S) + (Right: Abstract_value.S) = struct include Datatype.Pair (Left) (Right) - let structure = Structure.Key_Value.Node (Left.structure, Right.structure) - let pretty_typ typ = Pretty_utils.pp_pair ~pre:"@[" ~sep:",@ " ~suf:"@]" (Left.pretty_typ typ) (Right.pretty_typ typ) diff --git a/src/plugins/value/values/value_product.mli b/src/plugins/value/values/value_product.mli index f6369ee2efd75c5241cb13ca4243de875428f610..c24505d85e3f7e748301f1d05570e6df56b137d5 100644 --- a/src/plugins/value/values/value_product.mli +++ b/src/plugins/value/values/value_product.mli @@ -23,9 +23,9 @@ (** Cartesian product of two value abstractions. *) module Make - (Left: Abstract_value.Internal) - (Right: Abstract_value.Internal) - : Abstract_value.Internal with type t = Left.t * Right.t + (Left: Abstract_value.S) + (Right: Abstract_value.S) + : Abstract_value.S with type t = Left.t * Right.t (*