From 1ba76928e7365567ee4a8ae58c7cd84bbc596ceb Mon Sep 17 00:00:00 2001 From: Patrick Baudin <patrick.baudin@cea.fr> Date: Fri, 24 Jun 2022 16:05:56 +0200 Subject: [PATCH] [Pdg] removing Pdg from Db --- src/kernel_services/plugin_entry_points/db.ml | 80 ---- .../plugin_entry_points/db.mli | 323 ---------------- src/plugins/impact/compute_impact.ml | 34 +- src/plugins/impact/dune | 3 +- src/plugins/impact/gui/dune | 2 +- src/plugins/impact/gui/register_gui.ml | 7 +- src/plugins/impact/pdg_aux.ml | 4 +- src/plugins/impact/pdg_aux.mli | 11 +- src/plugins/impact/reason_graph.ml | 2 +- src/plugins/pdg/Pdg.ml | 5 +- src/plugins/pdg/Pdg.mli | 5 +- src/plugins/pdg/annot.ml | 8 +- src/plugins/pdg/api.ml | 111 ++++++ src/plugins/pdg/api.mli | 350 ++++++++++++++++++ src/plugins/pdg/marks.ml | 14 +- src/plugins/pdg/pdg_tbl.ml | 59 +++ src/plugins/pdg/pdg_tbl.mli | 44 +++ src/plugins/pdg/register.ml | 94 +---- src/plugins/postdominators/print.ml | 2 +- src/plugins/scope/defs.ml | 28 +- src/plugins/scope/dune | 3 +- src/plugins/scope/zones.ml | 6 +- src/plugins/security_slicing/components.ml | 78 ++-- src/plugins/security_slicing/dune | 3 +- src/plugins/slicing/fct_slice.ml | 42 +-- src/plugins/slicing/printSlice.ml | 2 +- src/plugins/slicing/slicingActions.ml | 10 +- src/plugins/slicing/slicingActions.mli | 2 +- src/plugins/slicing/slicingMacros.ml | 2 +- src/plugins/slicing/slicingMacros.mli | 4 +- src/plugins/slicing/slicingSelect.ml | 90 ++--- src/plugins/slicing/slicingSelect.mli | 4 +- src/plugins/slicing/slicingState.ml | 2 +- src/plugins/slicing/slicingTransform.ml | 20 +- src/plugins/sparecode/globs.ml | 2 +- src/plugins/sparecode/register.ml | 2 +- src/plugins/sparecode/spare_marks.ml | 18 +- src/plugins/sparecode/transform.ml | 2 +- tests/pdg/dyn_dpds.ml | 16 +- tests/pdg/sets.ml | 19 +- tests/slicing/libSelect.ml | 2 +- tests/slicing/min_call.ml | 8 +- tests/slicing/select_by_annot.ml | 2 +- tests/slicing/simple_intra_slice.ml | 2 +- 44 files changed, 801 insertions(+), 726 deletions(-) create mode 100644 src/plugins/pdg/api.ml create mode 100644 src/plugins/pdg/api.mli create mode 100644 src/plugins/pdg/pdg_tbl.ml create mode 100644 src/plugins/pdg/pdg_tbl.mli diff --git a/src/kernel_services/plugin_entry_points/db.ml b/src/kernel_services/plugin_entry_points/db.ml index 64e5c108ab5..4d69ac1a7f4 100644 --- a/src/kernel_services/plugin_entry_points/db.ml +++ b/src/kernel_services/plugin_entry_points/db.ml @@ -708,86 +708,6 @@ module From = struct end end -(* ************************************************************************* *) -(** {2 PDG} *) -(* ************************************************************************* *) - -module Pdg = struct - type t = PdgTypes.Pdg.t - - type t_nodes_and_undef = - ((PdgTypes.Node.t * Locations.Zone.t option) list * Locations.Zone.t option) - - exception Top = PdgTypes.Pdg.Top - exception Bottom = PdgTypes.Pdg.Bottom - - let self = ref State.dummy - - let get = mk_fun "Pdg.get" - - let from_same_fun pdg1 pdg2 = - let kf1 = PdgTypes.Pdg.get_kf pdg1 in - let kf2 = PdgTypes.Pdg.get_kf pdg2 in - Kernel_function.equal kf1 kf2 - - let node_key = mk_fun "Pdg.node_key" - - let find_decl_var_node = mk_fun "Pdg.find_decl_var_node" - let find_input_node = mk_fun "Pdg.find_input_nodes" - let find_ret_output_node = mk_fun "Pdg.find_ret_output_node" - let find_output_nodes = mk_fun "Pdg.find_output_nodes" - let find_all_inputs_nodes = mk_fun "Pdg.find_all_inputs_nodes" - let find_stmt_and_blocks_nodes = mk_fun "Pdg.find_stmt_and_blocks_nodes" - let find_simple_stmt_nodes = mk_fun "Pdg.find_simplestmt_nodes" - let find_stmt_node = mk_fun "Pdg.find_stmt_node" - let find_label_node = mk_fun "Pdg.find_label_node" - let find_entry_point_node = mk_fun "Pdg.find_entry_point_node" - let find_top_input_node = mk_fun "Pdg.find_top_input_node" - let find_call_ctrl_node = mk_fun "Pdg.find_call_ctrl_node" - let find_location_nodes_at_stmt = mk_fun "Pdg.find_location_nodes_at_stmt" - let find_location_nodes_at_end = mk_fun "Pdg.find_location_nodes_at_end" - let find_location_nodes_at_begin = mk_fun "Pdg.find_location_nodes_at_begin" - let find_call_input_node = mk_fun "Pdg.find_call_input_node" - let find_call_output_node = mk_fun "Pdg.find_call_output_node" - let find_code_annot_nodes = mk_fun "Pdg.find_code_annot_nodes" - let find_fun_precond_nodes = mk_fun "Pdg.find_fun_precond_nodes" - let find_fun_postcond_nodes = mk_fun "Pdg.find_fun_postcond_nodes" - let find_fun_variant_nodes = mk_fun "Pdg.find_fun_variant_nodes" - - let find_call_out_nodes_to_select = mk_fun "Pdg.find_call_out_nodes_to_select" - let find_in_nodes_to_select_for_this_call = - mk_fun "Pdg.find_in_nodes_to_select_for_this_call" - - let direct_dpds = mk_fun "Pdg.direct_dpds" - let direct_ctrl_dpds = mk_fun "Pdg.direct_ctrl_dpds" - let direct_data_dpds = mk_fun "Pdg.direct_data_dpds" - let direct_addr_dpds = mk_fun "Pdg.direct_addr_dpds" - - let all_dpds = mk_fun "Pdg.all_dpds" - let all_ctrl_dpds = mk_fun "Pdg.all_ctrl_dpds" - let all_data_dpds = mk_fun "Pdg.all_data_dpds" - let all_addr_dpds = mk_fun "Pdg.all_addr_dpds" - - let direct_uses = mk_fun "Pdg.direct_uses" - let direct_ctrl_uses = mk_fun "Pdg.direct_ctrl_uses" - let direct_data_uses = mk_fun "Pdg.direct_data_uses" - let direct_addr_uses = mk_fun "Pdg.direct_addr_uses" - - let all_uses = mk_fun "Pdg.all_uses" - - let custom_related_nodes = mk_fun "Pdg.custom_related_nodes" - - let find_call_stmts = mk_fun "Pdg.find_call_stmts" - - let iter_nodes = mk_fun "Pdg.iter_nodes" - - let extract = mk_fun "Pdg.extract" - let pretty = ref (fun ?bw:_ _ _ -> mk_labeled_fun "Pdg.pretty") - let pretty_node = mk_fun "Pdg.pretty_node" - let pretty_key = mk_fun "Pdg.pretty_key" - -end - (* ************************************************************************* *) (** {2 Properties} *) (* ************************************************************************* *) diff --git a/src/kernel_services/plugin_entry_points/db.mli b/src/kernel_services/plugin_entry_points/db.mli index 905663fa636..62334a53e2e 100644 --- a/src/kernel_services/plugin_entry_points/db.mli +++ b/src/kernel_services/plugin_entry_points/db.mli @@ -844,329 +844,6 @@ module Security : sig end -(** Program Dependence Graph. - @see <../pdg/index.html> PDG internal documentation. *) -module Pdg : sig - - exception Bottom - (** Raised by most function when the PDG is Bottom because we can hardly do - nothing with it. It happens when the function is unreachable because we - have no information about it. *) - - exception Top - (** Raised by most function when the PDG is Top because we can hardly do - nothing with it. It happens when we didn't manage to compute it, for - instance for a variadic function. *) - - type t = PdgTypes.Pdg.t - (** PDG type *) - - type t_nodes_and_undef = - ((PdgTypes.Node.t * Locations.Zone.t option) list * Locations.Zone.t option) - (** type for the return value of many [find_xxx] functions when the - answer can be a list of [(node, z_part)] and an [undef zone]. - For each node, [z_part] can specify which part of the node - is used in terms of zone ([None] means all). - *) - - val self : State.t ref - - (** {3 Getters} *) - - val get : (kernel_function -> t) ref - (** Get the PDG of a function. Build it if it doesn't exist yet. *) - - val node_key : (PdgTypes.Node.t -> PdgIndex.Key.t) ref - - val from_same_fun : t -> t -> bool - - (** {3 Finding PDG nodes} *) - - val find_decl_var_node : (t -> Cil_types.varinfo -> PdgTypes.Node.t) ref - (** Get the node corresponding the declaration of a local variable or a - formal parameter. - @raise Not_found if the variable is not declared in this function. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_ret_output_node : (t -> PdgTypes.Node.t) ref - (** Get the node corresponding return stmt. - @raise Not_found if the output state in unreachable - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_output_nodes : - (t -> PdgIndex.Signature.out_key -> t_nodes_and_undef) ref - (** Get the nodes corresponding to a call output key in the called pdg. - @raise Not_found if the output state in unreachable - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_input_node : (t -> int -> PdgTypes.Node.t) ref - (** Get the node corresponding to a given input (parameter). - @raise Not_found if the number is not an input number. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_all_inputs_nodes : (t -> PdgTypes.Node.t list) ref - (** Get the nodes corresponding to all inputs. - {!node_key} can be used to know their numbers. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_stmt_node : (t -> Cil_types.stmt -> PdgTypes.Node.t) ref - (** Get the node corresponding to the statement. - It shouldn't be a call statement. - See also {!find_simple_stmt_nodes} or {!find_call_stmts}. - @raise Not_found if the given statement is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. - @raise PdgIndex.CallStatement if the given stmt is a function - call. *) - - - val find_simple_stmt_nodes : (t -> Cil_types.stmt -> PdgTypes.Node.t list) ref - (** Get the nodes corresponding to the statement. - It is usually composed of only one node (see {!find_stmt_node}), - except for call statement. - Be careful that for block statements, it only returns a node - corresponding to the elementary stmt - (see {!find_stmt_and_blocks_nodes} for more) - @raise Not_found if the given statement is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_label_node : (t -> Cil_types.stmt -> Cil_types.label -> PdgTypes.Node.t) ref - (** Get the node corresponding to the label. - @raise Not_found if the given label is not in the PDG. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_stmt_and_blocks_nodes : (t -> Cil_types.stmt -> PdgTypes.Node.t list) ref - (** Get the nodes corresponding to the statement like - * {!find_simple_stmt_nodes} but also add the nodes of the enclosed - * statements if [stmt] contains blocks. - @raise Not_found if the given statement is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_top_input_node : (t -> PdgTypes.Node.t) ref - (** @raise Not_found if there is no top input in the PDG. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_entry_point_node : (t -> PdgTypes.Node.t) ref - (** Find the node that represent the entry point of the function, i.e. the - higher level block. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_location_nodes_at_stmt : - (t -> Cil_types.stmt -> before:bool -> Locations.Zone.t - -> t_nodes_and_undef) ref - (** Find the nodes that define the value of the location at the given - program point. Also return a zone that might be undefined at that - point. - @raise Not_found if the given statement is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_location_nodes_at_end : - (t -> Locations.Zone.t -> t_nodes_and_undef) ref - (** Same than {!find_location_nodes_at_stmt} for the program point located - at the end of the function. - @raise Not_found if the output state is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_location_nodes_at_begin : - (t -> Locations.Zone.t -> t_nodes_and_undef) ref - (** Same than {!find_location_nodes_at_stmt} for the program point located - at the beginning of the function. - Notice that it can only find formal argument nodes. - The remaining zone (implicit input) is returned as undef. - @raise Not_found if the output state is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_call_stmts: - (kernel_function -> caller:kernel_function -> Cil_types.stmt list) ref - (** Find the call statements to the function (can maybe be somewhere - else). - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_call_ctrl_node : (t -> Cil_types.stmt -> PdgTypes.Node.t) ref - (** @raise Not_found if the call is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_call_input_node : (t -> Cil_types.stmt -> int -> PdgTypes.Node.t) ref - (** @raise Not_found if the call is unreachable or has no such input. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_call_output_node : (t -> Cil_types.stmt -> PdgTypes.Node.t) ref - (** @raise Not_found if the call is unreachable or has no output node. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_code_annot_nodes : - (t -> Cil_types.stmt -> Cil_types.code_annotation -> - PdgTypes.Node.t list * PdgTypes.Node.t list * (t_nodes_and_undef option)) ref - (** The result is composed of three parts : - - the first part of the result are the control dependencies nodes - of the annotation, - - the second part is the list of declaration nodes of the variables - used in the annotation; - - the third part is similar to [find_location_nodes_at_stmt] result - but for all the locations needed by the annotation. - When the third part is globally [None], - it means that we were not able to compute this information. - @raise Not_found if the statement is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val find_fun_precond_nodes : - (t -> Cil_types.predicate -> PdgTypes.Node.t list * (t_nodes_and_undef option)) ref - (** Similar to [find_code_annot_nodes] (no control dependencies nodes) *) - - val find_fun_postcond_nodes : - (t -> Cil_types.predicate -> PdgTypes.Node.t list * (t_nodes_and_undef option)) ref - (** Similar to [find_fun_precond_nodes] *) - - val find_fun_variant_nodes : - (t -> Cil_types.term -> (PdgTypes.Node.t list * t_nodes_and_undef option)) ref - (** Similar to [find_fun_precond_nodes] *) - - (** {3 Propagation} - See also [Pdg.mli] for more function that cannot be here because - they use polymorphic types. - **) - - val find_call_out_nodes_to_select : - (t -> PdgTypes.NodeSet.t -> t -> Cil_types.stmt -> PdgTypes.Node.t list) ref - (** [find_call_out_nodes_to_select pdg_called called_selected_nodes - pdg_caller call_stmt] - @return the call outputs nodes [out] such that - [find_output_nodes pdg_called out_key] - intersects [called_selected_nodes]. *) - - val find_in_nodes_to_select_for_this_call : - (t -> PdgTypes.NodeSet.t -> Cil_types.stmt -> t -> PdgTypes.Node.t list) ref - (** [find_in_nodes_to_select_for_this_call - pdg_caller caller_selected_nodes call_stmt pdg_called] - @return the called input nodes such that the corresponding nodes - in the caller intersect [caller_selected_nodes] - @raise Not_found if the statement is unreachable. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - (** {3 Dependencies} *) - - val direct_dpds : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** Get the nodes to which the given node directly depend on. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val direct_ctrl_dpds : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** Similar to {!direct_dpds}, but for control dependencies only. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val direct_data_dpds : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** Similar to {!direct_dpds}, but for data dependencies only. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val direct_addr_dpds : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** Similar to {!direct_dpds}, but for address dependencies only. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val all_dpds : (t -> PdgTypes.Node.t list -> PdgTypes.Node.t list) ref - (** Transitive closure of {!direct_dpds} for all the given nodes. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val all_data_dpds : (t -> PdgTypes.Node.t list -> PdgTypes.Node.t list) ref - (** Gives the data dependencies of the given nodes, and recursively, all - the dependencies of those nodes (regardless to their kind). - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val all_ctrl_dpds : (t -> PdgTypes.Node.t list -> PdgTypes.Node.t list) ref - (** Similar to {!all_data_dpds} for control dependencies. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val all_addr_dpds : (t -> PdgTypes.Node.t list -> PdgTypes.Node.t list) ref - (** Similar to {!all_data_dpds} for address dependencies. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val direct_uses : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** build a list of all the nodes that have direct dependencies on the - given node. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val direct_ctrl_uses : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** Similar to {!direct_uses}, but for control dependencies only. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val direct_data_uses : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** Similar to {!direct_uses}, but for data dependencies only. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val direct_addr_uses : (t -> PdgTypes.Node.t -> PdgTypes.Node.t list) ref - (** Similar to {!direct_uses}, but for address dependencies only. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val all_uses : (t -> PdgTypes.Node.t list -> PdgTypes.Node.t list) ref - (** build a list of all the nodes that have dependencies (even indirect) on - the given nodes. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val custom_related_nodes : - ((PdgTypes.Node.t -> PdgTypes.Node.t list) -> PdgTypes.Node.t list -> PdgTypes.Node.t list) ref - (** [custom_related_nodes get_dpds node_list] build a list, starting from - the node in [node_list], and recursively add the nodes given by the - function [get_dpds]. For this function to work well, it is important - that [get_dpds n] returns a subset of the nodes directly related to - [n], ie a subset of [direct_uses] U [direct_dpds]. - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - val iter_nodes : ((PdgTypes.Node.t -> unit) -> t -> unit) ref - (** apply a given function to all the PDG nodes - @raise Bottom if given PDG is bottom. - @raise Top if the given pdg is top. *) - - (** {3 Pretty printing} *) - - val extract : (t -> string -> unit) ref - (** Pretty print pdg into a dot file. - @see <../pdg/index.html> PDG internal documentation. *) - - val pretty_node : (bool -> Format.formatter -> PdgTypes.Node.t -> unit) ref - (** Pretty print information on a node : with [short=true], only the id - of the node is printed.. *) - - val pretty_key : (Format.formatter -> PdgIndex.Key.t -> unit) ref - (** Pretty print information on a node key *) - - val pretty : (?bw:bool -> Format.formatter -> t -> unit) ref - (** For debugging... Pretty print pdg information. - Print codependencies rather than dependencies if [bw=true]. *) - -end - - (** Signature common to some Inout plugin options. The results of the computations are available on a per function basis. *) module type INOUTKF = sig diff --git a/src/plugins/impact/compute_impact.ml b/src/plugins/impact/compute_impact.ml index 1744f0a3e7d..f8d9abc1c11 100644 --- a/src/plugins/impact/compute_impact.ml +++ b/src/plugins/impact/compute_impact.ml @@ -166,7 +166,7 @@ let add_to_result wl n kf init = (** return [true] if the location in [n] is contained in [skip], in which case the node should be skipped entirely *) let node_to_skip skip n = - match !Db.Pdg.node_key n with + match Pdg.Api.node_key n with | Key.SigKey (Signature.In (Signature.InImpl z)) | Key.SigKey (Signature.Out (Signature.OutLoc z)) | Key.SigCallKey (_, Signature.In (Signature.InImpl z)) @@ -179,7 +179,7 @@ let node_to_skip skip n = the results *) let filter wl (n, z) = not (Locations.Zone.is_bottom z) && - match !Db.Pdg.node_key n with + match Pdg.Api.node_key n with | Key.SigKey (Signature.In Signature.InCtrl) -> false (* do not consider node [InCtrl]. YYY: find when this may happen *) | Key.VarDecl _ -> false @@ -320,7 +320,7 @@ let add_downward_call wl (caller_kf, pdg) (called_kf, called_pdg) stmt = callee are directly in the worklist, and the call is registered in the field [downward_calls]. *) let downward_one_call_node wl (pnode, _ as node) caller_kf pdg = - match !Db.Pdg.node_key pnode with + match Pdg.Api.node_key pnode with | Key.SigKey (Signature.In Signature.InCtrl) (* never in the worklist *) | Key.VarDecl _ (* never in the worklist *) | Key.CallStmt _ (* pdg returns a SigCallKey instead *) @@ -335,31 +335,31 @@ let downward_one_call_node wl (pnode, _ as node) caller_kf pdg = let called_kfs = Eva.Results.callee stmt in List.iter (fun called_kf -> - let called_pdg = !Db.Pdg.get called_kf in + let called_pdg = Pdg.Api.get called_kf in let nodes_callee, pdg_ok = Options.debug ~level:3 "%a: considering call to %a" Pdg_aux.pretty_node node Kernel_function.pretty called_kf; try (match key with | Signature.In (Signature.InNum n) -> - (try [!Db.Pdg.find_input_node called_pdg n, + (try [Pdg.Api.find_input_node called_pdg n, Locations.Zone.top] with Not_found -> []) | Signature.In Signature.InCtrl -> - (try [!Db.Pdg.find_entry_point_node called_pdg, + (try [Pdg.Api.find_entry_point_node called_pdg, Locations.Zone.top] with Not_found -> []) | Signature.In (Signature.InImpl _) -> assert false | Signature.Out _ -> [] ), true with - | Db.Pdg.Top -> + | Pdg.Api.Top -> Options.warning "no precise pdg for function %s. \n\ Ignoring this function in the analysis (potentially incorrect results)." (Kernel_function.get_name called_kf); [], false - | Db.Pdg.Bottom -> + | Pdg.Api.Bottom -> (*Function that fails or never returns immediately *) [], false | Not_found -> assert false @@ -398,7 +398,7 @@ let downward_one_call_inputs wl kf_caller kf_callee (node, deps) = (fun nsrc -> add_to_reason wl ~nsrc ~ndst:node' InterproceduralDownward) inter; - add_to_do wl kf_callee (!Db.Pdg.get kf_callee) node'; + add_to_do wl kf_callee (Pdg.Api.get kf_callee) node'; ;; (** Propagate impact for all calls registered in [downward_calls]. For each @@ -447,10 +447,10 @@ let all_upward_callers wl kfs = let todo = if not (KFS.mem kf wl.callers) then ( Options.debug "Found caller %a" Kernel_function.pretty kf; - let pdg_kf = !Db.Pdg.get kf in + let pdg_kf = Pdg.Api.get kf in List.fold_left (fun todo (caller, callsites) -> - let pdg_caller = !Db.Pdg.get caller in + let pdg_caller = Pdg.Api.get caller in List.iter (aux_call (caller, pdg_caller) (kf, pdg_kf)) callsites; KFS.add caller todo ) todo (Eva.Results.callsites kf); @@ -486,9 +486,9 @@ let upward_in_callers wl = add_to_reason wl ~nsrc ~ndst:n InterproceduralUpward ) inter; if init then - add_to_do_part_of_initial wl caller (!Db.Pdg.get caller) n + add_to_do_part_of_initial wl caller (Pdg.Api.get caller) n else - add_to_do wl caller (!Db.Pdg.get caller) n + add_to_do wl caller (Pdg.Api.get caller) n ) (Lazy.force l) in KfKfCall.Map.iter aux wl.upward_calls; @@ -522,7 +522,7 @@ let initial_worklist ?(skip=Locations.Zone.bottom) ?(reason=false) nodes kf = } in (* Fill the [todo] field *) - initial_to_do_list wl kf (!Db.Pdg.get kf) nodes; + initial_to_do_list wl kf (Pdg.Api.get kf) nodes; let initial_callers = if Options.Upward.get () then KFS.singleton kf else KFS.empty in @@ -536,10 +536,10 @@ let initial_worklist ?(skip=Locations.Zone.bottom) ?(reason=false) nodes kf = callees of the call. *) let initial_nodes ~skip kf stmt = Options.debug ~level:3 "computing initial nodes for %d" stmt.sid; - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in if Eva.Results.is_reachable stmt then try - let all = !Db.Pdg.find_simple_stmt_nodes pdg stmt in + let all = Pdg.Api.find_simple_stmt_nodes pdg stmt in let filter n = match PdgTypes.Node.elem_key n with | Key.SigCallKey (_, Signature.In _) -> false | _ -> not (node_to_skip skip n) @@ -669,7 +669,7 @@ let result_to_nodes (res: result) : nodes = (** Transform a set of PDG nodes into a set of statements *) let nodes_to_stmts ns = - let get_stmt node = Key.stmt (!Db.Pdg.node_key node) in + let get_stmt node = Key.stmt (Pdg.Api.node_key node) in let set = (* Do not generate a list immediately, some nodes would be duplicated *) NS.fold diff --git a/src/plugins/impact/dune b/src/plugins/impact/dune index 734041fbd96..6bcede10dbb 100644 --- a/src/plugins/impact/dune +++ b/src/plugins/impact/dune @@ -28,6 +28,7 @@ (echo " - Callgraph:" %{lib-available:frama-c-callgraph.core} "\n") (echo " - Slicing:" %{lib-available:frama-c-slicing.core} "\n") (echo " - Inout:" %{lib-available:frama-c-inout.core} "\n") + (echo " - Pdg:" %{lib-available:frama-c-pdg.core} "\n") ) ) ) @@ -38,7 +39,7 @@ (optional) (public_name frama-c-impact.core) (flags -open Frama_c_kernel :standard -w -9) - (libraries frama-c.kernel frama-c-slicing.core frama-c-callgraph.core frama-c-inout.core) + (libraries frama-c.kernel frama-c-pdg.core frama-c-slicing.core frama-c-callgraph.core frama-c-inout.core) ) (plugin (optional) (name impact) (libraries frama-c-impact.core) (site (frama-c plugins))) diff --git a/src/plugins/impact/gui/dune b/src/plugins/impact/gui/dune index 39db9c604ef..e00946f6944 100644 --- a/src/plugins/impact/gui/dune +++ b/src/plugins/impact/gui/dune @@ -25,7 +25,7 @@ (public_name frama-c-impact.gui) (optional) (flags -open Frama_c_kernel -open Frama_c_gui -open Impact :standard -w -9) - (libraries frama-c.kernel frama-c.gui frama-c-impact.core frama-c-slicing.core frama-c-callgraph.core) + (libraries frama-c.kernel frama-c.gui frama-c-pdg.core frama-c-impact.core frama-c-slicing.core frama-c-callgraph.core) ) (plugin (optional) (name impact-gui) (libraries frama-c-impact.gui) (site (frama-c plugins_gui))) diff --git a/src/plugins/impact/gui/register_gui.ml b/src/plugins/impact/gui/register_gui.ml index 5146cb4a509..bdbc771e13c 100644 --- a/src/plugins/impact/gui/register_gui.ml +++ b/src/plugins/impact/gui/register_gui.ml @@ -22,7 +22,6 @@ open Pretty_source open Gtk_helper -open Db open Cil_types module SelectedStmt = struct @@ -43,7 +42,7 @@ let () = (fun () -> State_dependency_graph.add_codependencies ~onto:SelectedStmt.self - [ !Db.Pdg.self ]) + [ Pdg.Api.self ]) module Highlighted_stmt : sig val add: Kernel_function.t -> stmt -> unit @@ -232,7 +231,7 @@ let pp_impact_on_inputs (main_ui:Design.main_window_extension_points) kf = let call, formals, zones = Pdg_aux.NS.fold (fun (node, z) (call, formals, zones as acc) -> - match !Pdg.node_key node with + match Pdg.Api.node_key node with | SigCallKey _ | CallStmt _ | Stmt _ | Label _ -> acc (* Related to one stmt: skip *) | VarDecl _ -> acc (* skip *) @@ -268,7 +267,7 @@ let pp_impacted_call_outputs let ret, zones = Pdg_aux.NS.fold (fun (node, z) (ret, zones as acc) -> - match !Pdg.node_key node with + match Pdg.Api.node_key node with | SigCallKey (stmt', key) when Cil_datatype.Stmt.equal call_stmt stmt' -> (match key with diff --git a/src/plugins/impact/pdg_aux.ml b/src/plugins/impact/pdg_aux.ml index 8513bcf2411..c36b4d651b9 100644 --- a/src/plugins/impact/pdg_aux.ml +++ b/src/plugins/impact/pdg_aux.ml @@ -159,7 +159,7 @@ let find_call_input_nodes pdg_caller call_stmt ?(z=Locations.Zone.top) in_key = (* skip undef zone: any result different from None is due to calldeps or some imprecision. *) let nodes, _undef = - !Db.Pdg.find_location_nodes_at_stmt + Pdg.Api.find_location_nodes_at_stmt pdg_caller call_stmt ~before:true zone' in nodes @@ -201,7 +201,7 @@ let all_call_out_nodes ~callee ~caller call_stmt = in let test_out acc (out_key, call_out_node) = (* skip undef: any zone found undef is due to an imprecision or a bug*) - let out_nodes, _ = !Db.Pdg.find_output_nodes callee out_key in + let out_nodes, _ = Pdg.Api.find_output_nodes callee out_key in let out_nodes = node_list_to_set out_nodes in (call_out_node, out_nodes) :: acc in diff --git a/src/plugins/impact/pdg_aux.mli b/src/plugins/impact/pdg_aux.mli index 32e7f34d68c..fa3bcde2b5f 100644 --- a/src/plugins/impact/pdg_aux.mli +++ b/src/plugins/impact/pdg_aux.mli @@ -21,7 +21,6 @@ (**************************************************************************) open Cil_types -open PdgTypes open Locations (** Useful functions that are not directly accessible through the other @@ -30,7 +29,7 @@ open Locations (** Refinement of a PDG node: we add an indication of which zone is really impacted *) -type node = Node.t * Zone.t +type node = PdgTypes.Node.t * Zone.t val pretty_node: node Pretty_utils.formatter @@ -53,9 +52,9 @@ module NS: sig val inter: t -> t -> t val diff: t -> t -> t - val remove: Node.t -> t -> t + val remove: PdgTypes.Node.t -> t -> t - val mem: Node.t -> t -> bool + val mem: PdgTypes.Node.t -> t -> bool val mem': node -> t -> bool val intersects: t -> t -> bool val for_all': (node -> bool) -> t -> bool @@ -76,7 +75,7 @@ type call_interface = (PdgTypes.Node.t * NS.t) list of [callee]. Each input node in [callee] is returned with the set of nodes that define it in [caller]. *) val all_call_input_nodes: - caller:Db.Pdg.t -> callee:kernel_function * Db.Pdg.t -> stmt -> + caller:Pdg.Api.t -> callee:kernel_function * Pdg.Api.t -> stmt -> call_interface (** [all_call_out_nodes ~callee ~caller stmt] find all the nodes of [callee] @@ -84,4 +83,4 @@ val all_call_input_nodes: that occurs at [stmt]. Each such out node is returned, with the set of nodes that define it in [callee] *) val all_call_out_nodes : - callee:Db.Pdg.t -> caller:Db.Pdg.t -> stmt -> call_interface + callee:Pdg.Api.t -> caller:Pdg.Api.t -> stmt -> call_interface diff --git a/src/plugins/impact/reason_graph.ml b/src/plugins/impact/reason_graph.ml index eceba7800cf..f3242116b75 100644 --- a/src/plugins/impact/reason_graph.ml +++ b/src/plugins/impact/reason_graph.ml @@ -216,7 +216,7 @@ let print_dot_graph reason = (* Very basic textual debugging function *) let _print_reason reason = - let pp_node = !Db.Pdg.pretty_node false in + let pp_node = Pdg.Api.pretty_node false in let pp fmt (nsrc, ndst, reason) = Format.fprintf fmt "@[<v 2>%a -> %a (%s)@]" pp_node nsrc pp_node ndst diff --git a/src/plugins/pdg/Pdg.ml b/src/plugins/pdg/Pdg.ml index 40d3a563379..4838045256c 100644 --- a/src/plugins/pdg/Pdg.ml +++ b/src/plugins/pdg/Pdg.ml @@ -22,7 +22,6 @@ (** Program Dependences Graph. *) -(** Functions for this plugin are registered through the [Db] module, - the dynamic API, and the module Below. *) - module Register = Register + +module Api = Api diff --git a/src/plugins/pdg/Pdg.mli b/src/plugins/pdg/Pdg.mli index 2fcfa888531..1ba848dc619 100644 --- a/src/plugins/pdg/Pdg.mli +++ b/src/plugins/pdg/Pdg.mli @@ -22,7 +22,6 @@ (** Program Dependences Graph. *) -(** Functions for this plugin are registered through the [Db] module, - the dynamic API, and the module Below. *) - module Register : module type of Marks + +module Api : module type of Api diff --git a/src/plugins/pdg/annot.ml b/src/plugins/pdg/annot.ml index d76dc95c38d..00b327ff190 100644 --- a/src/plugins/pdg/annot.ml +++ b/src/plugins/pdg/annot.ml @@ -117,13 +117,13 @@ let find_code_annot_nodes pdg stmt annot = let labels = decl_label_info.Db.Properties.Interp.To_zone.lbl in let stmt_key = Key.stmt_key stmt in let stmt_node = match stmt_key with - | Key.Stmt _ -> !Db.Pdg.find_stmt_node pdg stmt - | Key.CallStmt _ -> !Db.Pdg.find_call_ctrl_node pdg stmt + | Key.Stmt _ -> Sets.find_stmt_node pdg stmt + | Key.CallStmt _ -> Sets.find_call_ctrl_node pdg stmt | _ -> assert false in - let ctrl_dpds = !Db.Pdg.direct_ctrl_dpds pdg stmt_node in + let ctrl_dpds = Sets.direct_ctrl_dpds pdg stmt_node in let add_stmt_nodes s acc = - try !Db.Pdg.find_stmt_and_blocks_nodes pdg s @ acc + try Sets.find_stmt_and_blocks_nodes pdg s @ acc with Not_found -> acc in (* can safely ignore pragmas.ctrl diff --git a/src/plugins/pdg/api.ml b/src/plugins/pdg/api.ml new file mode 100644 index 00000000000..2dcc57f4a5c --- /dev/null +++ b/src/plugins/pdg/api.ml @@ -0,0 +1,111 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2022 *) +(* 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). *) +(* *) +(**************************************************************************) + +[@@@ warning "-32" ] + +type t = PdgTypes.Pdg.t + +type t_nodes_and_undef = + ((PdgTypes.Node.t * Locations.Zone.t option) list * Locations.Zone.t option) + +exception Top = PdgTypes.Pdg.Top +exception Bottom = PdgTypes.Pdg.Bottom + +(**************************************************************************) + +let self = Pdg_tbl.self +let get = Pdg_tbl.get + +let node_key = PdgTypes.Node.elem_key + +let from_same_fun pdg1 pdg2 = + let kf1 = PdgTypes.Pdg.get_kf pdg1 in + let kf2 = PdgTypes.Pdg.get_kf pdg2 in + Kernel_function.equal kf1 kf2 + +(**************************************************************************) +let find_decl_var_node = Sets.find_decl_var_node +let find_entry_point_node = Sets.find_entry_point_node +let find_top_input_node = Sets.find_top_input_node +let find_simple_stmt_nodes = Sets.find_simple_stmt_nodes +let find_stmt_and_blocks_nodes = Sets.find_stmt_and_blocks_nodes +let find_stmt_node = Sets.find_stmt_node +let find_label_node = Sets.find_label_node +let find_location_nodes_at_stmt = Sets.find_location_nodes_at_stmt +let find_location_nodes_at_begin = Sets.find_location_nodes_at_begin +let find_location_nodes_at_end = Sets.find_location_nodes_at_end +let find_call_ctrl_node = Sets.find_call_ctrl_node +let find_call_input_node = Sets.find_call_num_input_node +let find_call_output_node = Sets.find_call_output_node +let find_input_node = Sets.find_input_node +let find_ret_output_node = Sets.find_output_node +let find_output_nodes = Sets.find_output_nodes +let find_all_inputs_nodes = Sets.find_all_input_nodes + +let find_call_stmts = Sets.find_call_stmts + +let find_code_annot_nodes = Annot.find_code_annot_nodes +let find_fun_precond_nodes = Annot.find_fun_precond_nodes +let find_fun_postcond_nodes = Annot.find_fun_postcond_nodes +let find_fun_variant_nodes = Annot.find_fun_variant_nodes + +let find_call_out_nodes_to_select = Sets.find_call_out_nodes_to_select +let find_in_nodes_to_select_for_this_call = + Sets.find_in_nodes_to_select_for_this_call + +(**************************************************************************) + +let direct_dpds = Sets.direct_dpds +let direct_ctrl_dpds = Sets.direct_ctrl_dpds +let direct_data_dpds = Sets.direct_data_dpds +let direct_addr_dpds = Sets.direct_addr_dpds + +let all_dpds = Sets.find_nodes_all_dpds +let all_ctrl_dpds = Sets.find_nodes_all_ctrl_dpds +let all_data_dpds = Sets.find_nodes_all_data_dpds +let all_addr_dpds = Sets.find_nodes_all_addr_dpds + +let direct_uses = Sets.direct_uses +let direct_ctrl_uses = Sets.direct_ctrl_uses +let direct_data_uses = Sets.direct_data_uses +let direct_addr_uses = Sets.direct_addr_uses + +let all_uses = Sets.all_uses + +let custom_related_nodes = Sets.custom_related_nodes + +let iter_nodes = PdgTypes.Pdg.iter_nodes + +(**************************************************************************) + + +let extract = Pdg_tbl.print_dot + +let pretty_node = Pdg_tbl.pretty_node +let pretty_key = Pdg_tbl.pretty_key +let pretty = Pdg_tbl.pretty + +(**************************************************************************) + +module Marks = Marks + +(**************************************************************************) diff --git a/src/plugins/pdg/api.mli b/src/plugins/pdg/api.mli new file mode 100644 index 00000000000..c0a8fcf858c --- /dev/null +++ b/src/plugins/pdg/api.mli @@ -0,0 +1,350 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2022 *) +(* 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). *) +(* *) +(**************************************************************************) + +type t = PdgTypes.Pdg.t +(** Program Dependence Graph type *) + +type t_nodes_and_undef = + ((PdgTypes.Node.t * Locations.Zone.t option) list * Locations.Zone.t option) +(** type for the return value of many [find_xxx] functions when the + answer can be a list of [(node, z_part)] and an [undef zone]. + For each node, [z_part] can specify which part of the node + is used in terms of zone ([None] means all). *) + +(**************************************************************************) + +exception Bottom +(** Raised by most function when the PDG is Bottom because we can hardly do + nothing with it. It happens when the function is unreachable because we + have no information about it. *) + +exception Top +(** Raised by most function when the PDG is Top because we can hardly do + nothing with it. It happens when we didn't manage to compute it, for + instance for a variadic function. *) + +(**************************************************************************) + +val self : State.t +(** PDG depedency state *) + +(**************************************************************************) + +(** {3 Getters} *) + +val get : Cil_types.kernel_function -> t +(** Get the PDG of a function. Build it if it doesn't exist yet. *) + +val node_key : PdgTypes.Node.t -> PdgIndex.Key.t + +val from_same_fun : t -> t -> bool + +(**************************************************************************) + +(** {Finding PDG nodes} *) + +val find_decl_var_node : t -> Cil_types.varinfo -> PdgTypes.Node.t +(** Get the node corresponding the declaration of a local variable or a + formal parameter. + @raise Not_found if the variable is not declared in this function. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_ret_output_node : t -> PdgTypes.Node.t +(** Get the node corresponding return stmt. + @raise Not_found if the output state in unreachable + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_output_nodes : t -> PdgIndex.Signature.out_key -> t_nodes_and_undef +(** Get the nodes corresponding to a call output key in the called pdg. + @raise Not_found if the output state in unreachable + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_input_node : t -> int -> PdgTypes.Node.t +(** Get the node corresponding to a given input (parameter). + @raise Not_found if the number is not an input number. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_all_inputs_nodes : t -> PdgTypes.Node.t list +(** Get the nodes corresponding to all inputs. + {!node_key} can be used to know their numbers. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_stmt_node : t -> Cil_types.stmt -> PdgTypes.Node.t +(** Get the node corresponding to the statement. + It shouldn't be a call statement. + See also {!find_simple_stmt_nodes} or {!find_call_stmts}. + @raise Not_found if the given statement is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. + @raise PdgIndex.CallStatement if the given stmt is a function + call. *) + + +val find_simple_stmt_nodes : t -> Cil_types.stmt -> PdgTypes.Node.t list +(** Get the nodes corresponding to the statement. + It is usually composed of only one node (see {!find_stmt_node}), + except for call statement. + Be careful that for block statements, it only returns a node + corresponding to the elementary stmt + (see {!find_stmt_and_blocks_nodes} for more) + @raise Not_found if the given statement is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_label_node : t -> Cil_types.stmt -> Cil_types.label -> PdgTypes.Node.t +(** Get the node corresponding to the label. + @raise Not_found if the given label is not in the PDG. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_stmt_and_blocks_nodes : t -> Cil_types.stmt -> PdgTypes.Node.t list +(** Get the nodes corresponding to the statement like + {!find_simple_stmt_nodes} but also add the nodes of the enclosed + statements if [stmt] contains blocks. + @raise Not_found if the given statement is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_top_input_node : t -> PdgTypes.Node.t +(** @raise Not_found if there is no top input in the PDG. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_entry_point_node : t -> PdgTypes.Node.t +(** Find the node that represent the entry point of the function, i.e. the + higher level block. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_location_nodes_at_stmt : t -> Cil_types.stmt -> before:bool -> + Locations.Zone.t -> t_nodes_and_undef +(** Find the nodes that define the value of the location at the given + program point. Also return a zone that might be undefined at that point. + @raise Not_found if the given statement is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_location_nodes_at_end : t -> Locations.Zone.t -> t_nodes_and_undef +(** Same than {!find_location_nodes_at_stmt} for the program point located + at the end of the function. + @raise Not_found if the output state is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_location_nodes_at_begin : t -> Locations.Zone.t -> t_nodes_and_undef +(** Same than {!find_location_nodes_at_stmt} for the program point located + at the beginning of the function. + Notice that it can only find formal argument nodes. + The remaining zone (implicit input) is returned as undef. + @raise Not_found if the output state is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_call_stmts : Cil_types.kernel_function -> + caller:Cil_types.kernel_function -> Cil_types.stmt list +(** Find the call statements to the function (can maybe be somewhere + else). + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_call_ctrl_node : t -> Cil_types.stmt -> PdgTypes.Node.t +(** @raise Not_found if the call is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_call_input_node : t -> Cil_types.stmt -> int -> PdgTypes.Node.t +(** @raise Not_found if the call is unreachable or has no such input. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_call_output_node : t -> Cil_types.stmt -> PdgTypes.Node.t +(** @raise Not_found if the call is unreachable or has no output node. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_code_annot_nodes : t -> Cil_types.stmt -> + Cil_types.code_annotation -> + PdgTypes.Node.t list * PdgTypes.Node.t list * (t_nodes_and_undef option) +(** The result is composed of three parts : + - the first part of the result are the control dependencies nodes + of the annotation, + - the second part is the list of declaration nodes of the variables + used in the annotation; + - the third part is similar to [find_location_nodes_at_stmt] result + but for all the locations needed by the annotation. + When the third part is globally [None], + it means that we were not able to compute this information. + @raise Not_found if the statement is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val find_fun_precond_nodes : t -> Cil_types.predicate -> + PdgTypes.Node.t list * (t_nodes_and_undef option) +(** Similar to [find_code_annot_nodes] (no control dependencies nodes) *) + +val find_fun_postcond_nodes : t -> Cil_types.predicate -> + PdgTypes.Node.t list * (t_nodes_and_undef option) +(** Similar to [find_fun_precond_nodes] *) + +val find_fun_variant_nodes : t -> Cil_types.term -> + PdgTypes.Node.t list * (t_nodes_and_undef option) +(** Similar to [find_fun_precond_nodes] *) + +(**************************************************************************) + +(** {3 Propagation} + See also [Pdg.mli] for more function that cannot be here because + they use polymorphic types. **) + +val find_call_out_nodes_to_select : + t -> PdgTypes.NodeSet.t -> t -> Cil_types.stmt -> PdgTypes.Node.t list +(** [find_call_out_nodes_to_select pdg_called called_selected_nodes + pdg_caller call_stmt] + @return the call outputs nodes [out] such that + [find_output_nodes pdg_called out_key] + intersects [called_selected_nodes]. *) + +val find_in_nodes_to_select_for_this_call : + t -> PdgTypes.NodeSet.t -> Cil_types.stmt -> t -> PdgTypes.Node.t list +(** [find_in_nodes_to_select_for_this_call + pdg_caller caller_selected_nodes call_stmt pdg_called] + @return the called input nodes such that the corresponding nodes + in the caller intersect [caller_selected_nodes] + @raise Not_found if the statement is unreachable. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +(**************************************************************************) + +(** {3 Dependencies} *) + +val direct_dpds : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** Get the nodes to which the given node directly depend on. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val direct_ctrl_dpds : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** Similar to {!direct_dpds}, but for control dependencies only. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val direct_data_dpds : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** Similar to {!direct_dpds}, but for data dependencies only. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val direct_addr_dpds : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** Similar to {!direct_dpds}, but for address dependencies only. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val all_dpds : t -> PdgTypes.Node.t list -> PdgTypes.Node.t list +(** Transitive closure of {!direct_dpds} for all the given nodes. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val all_data_dpds : t -> PdgTypes.Node.t list -> PdgTypes.Node.t list +(** Gives the data dependencies of the given nodes, and recursively, all + the dependencies of those nodes (regardless to their kind). + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val all_ctrl_dpds : t -> PdgTypes.Node.t list -> PdgTypes.Node.t list +(** Similar to {!all_data_dpds} for control dependencies. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val all_addr_dpds : t -> PdgTypes.Node.t list -> PdgTypes.Node.t list +(** Similar to {!all_data_dpds} for address dependencies. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val direct_uses : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** build a list of all the nodes that have direct dependencies on the + given node. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val direct_ctrl_uses : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** Similar to {!direct_uses}, but for control dependencies only. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val direct_data_uses : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** Similar to {!direct_uses}, but for data dependencies only. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val direct_addr_uses : t -> PdgTypes.Node.t -> PdgTypes.Node.t list +(** Similar to {!direct_uses}, but for address dependencies only. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val all_uses : t -> PdgTypes.Node.t list -> PdgTypes.Node.t list +(** build a list of all the nodes that have dependencies (even indirect) on + the given nodes. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val custom_related_nodes : (PdgTypes.Node.t -> PdgTypes.Node.t list) -> + PdgTypes.Node.t list -> PdgTypes.Node.t list +(** [custom_related_nodes get_dpds node_list] build a list, starting from + the node in [node_list], and recursively add the nodes given by the + function [get_dpds]. For this function to work well, it is important + that [get_dpds n] returns a subset of the nodes directly related to + [n], ie a subset of [direct_uses] U [direct_dpds]. + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +val iter_nodes : (PdgTypes.Node.t -> unit) -> t -> unit +(** apply a given function to all the PDG nodes + @raise Bottom if given PDG is bottom. + @raise Top if the given pdg is top. *) + +(**************************************************************************) + +(** {3 Printers} *) + +val extract : t -> string -> unit +(** Pretty print pdg into a dot file. *) + +val pretty_node : bool -> Format.formatter -> PdgTypes.Node.t -> unit +(** Pretty print information on a node : with [short=true], only the id + of the node is printed.. *) + +val pretty_key : Format.formatter -> PdgIndex.Key.t -> unit +(** Pretty print information on a node key *) + +val pretty : ?bw:bool -> Format.formatter -> t -> unit +(** For debugging... Pretty print pdg information. + Print codependencies rather than dependencies if [bw=true]. *) + +(**************************************************************************) + +module Marks : module type of Marks + +(**************************************************************************) diff --git a/src/plugins/pdg/marks.ml b/src/plugins/pdg/marks.ml index 272b5b1ad9f..520249051f0 100644 --- a/src/plugins/pdg/marks.ml +++ b/src/plugins/pdg/marks.ml @@ -36,12 +36,12 @@ let in_marks_to_caller pdg call m2m ?(rqs=[]) in_marks = let build rqs (in_key, m) = match in_key with | Signature.InCtrl -> - add_n_m rqs (!Db.Pdg.find_call_ctrl_node pdg call) None m + add_n_m rqs (Sets.find_call_ctrl_node pdg call) None m | Signature.InNum in_num -> - add_n_m rqs (!Db.Pdg.find_call_input_node pdg call in_num) None m + add_n_m rqs (Sets.find_call_num_input_node pdg call in_num) None m | Signature.InImpl zone -> let nodes, undef = - !Db.Pdg.find_location_nodes_at_stmt pdg call ~before:true zone + Sets.find_location_nodes_at_stmt pdg call ~before:true zone in let rqs = List.fold_left (fun acc (n,z) -> add_n_m acc n z m) rqs nodes in @@ -64,10 +64,10 @@ let translate_in_marks pdg_called in_new_marks in_marks_to_caller pdg call (m2m (Some call) pdg) ~rqs in_new_marks in let build rqs caller = - let pdg_caller = !Db.Pdg.get caller in + let pdg_caller = Pdg_tbl.get caller in let caller_rqs = try - let call_stmts = !Db.Pdg.find_call_stmts ~caller kf_called in + let call_stmts = Sets.find_call_stmts ~caller kf_called in (* TODO : more intelligent merge ? *) let rqs = List.fold_left (translate pdg_caller) [] call_stmts in PdgMarks.SelList rqs @@ -98,7 +98,7 @@ let call_out_marks_to_called called_pdg m2m ?(rqs=[]) out_marks = let translate_out_mark _pdg m2m other_rqs (call, l) = let add_list l_out_m rqs called_kf = - let called_pdg = !Db.Pdg.get called_kf in + let called_pdg = Pdg_tbl.get called_kf in let m2m = m2m (Some call) called_pdg in try let node_marks = @@ -165,7 +165,7 @@ module F_Proj (C : PdgMarks.Config) : let fct_var = Kernel_function.get_vi kf in try Varinfo.Hashtbl.find proj fct_var with Not_found -> - let pdg = !Db.Pdg.get kf in + let pdg = Pdg_tbl.get kf in let info = F.create pdg in Varinfo.Hashtbl.add proj fct_var info; info diff --git a/src/plugins/pdg/pdg_tbl.ml b/src/plugins/pdg/pdg_tbl.ml new file mode 100644 index 00000000000..4961d4154bd --- /dev/null +++ b/src/plugins/pdg/pdg_tbl.ml @@ -0,0 +1,59 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2022 *) +(* 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). *) +(* *) +(**************************************************************************) + +type t = PdgTypes.Pdg.t + +(**************************************************************************) + +let compute = Build.compute_pdg + +module Tbl = + Kernel_function.Make_Table + (PdgTypes.Pdg) + (struct + let name = "Pdg.State" + let dependencies = [] (* postponed because !Db.From.self may + not exist yet *) + let size = 17 + end) + +let self = Tbl.self +let get = Tbl.memo compute + +(**************************************************************************) + +let pretty ?(bw=false) fmt pdg = + let kf = PdgTypes.Pdg.get_kf pdg in + Format.fprintf fmt "@[RESULT for %s:@]@\n@[ %a@]" + (Kernel_function.get_name kf) (PdgTypes.Pdg.pretty_bw ~bw) pdg + +let pretty_node short = + if short then PdgTypes.Node.pretty + else PdgTypes.Node.pretty_node + +let print_dot pdg filename = + PdgTypes.Pdg.build_dot filename pdg; + Pdg_parameters.feedback "dot file generated in %s" filename + +let pretty_key = PdgIndex.Key.pretty + +(**************************************************************************) diff --git a/src/plugins/pdg/pdg_tbl.mli b/src/plugins/pdg/pdg_tbl.mli new file mode 100644 index 00000000000..73bfa5d76ef --- /dev/null +++ b/src/plugins/pdg/pdg_tbl.mli @@ -0,0 +1,44 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2022 *) +(* 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). *) +(* *) +(**************************************************************************) + +type t = PdgTypes.Pdg.t + +val self : State.t + +val get : Cil_types.kernel_function -> t +(** Get the PDG of a function. Build it if it doesn't exist yet. *) + +(** {3 Pretty printing} *) + +val pretty_node : bool -> Format.formatter -> PdgTypes.Node.t -> unit +(** Pretty print information on a node : with [short=true], only the id + of the node is printed.. *) + +val pretty_key : Format.formatter -> PdgIndex.Key.t -> unit +(** Pretty print information on a node key *) + +val pretty : ?bw:bool -> Format.formatter -> t -> unit +(** For debugging... Pretty print pdg information. + Print codependencies rather than dependencies if [bw=true]. *) + +val print_dot : t -> string -> unit +(** Pretty print pdg into a dot file. *) diff --git a/src/plugins/pdg/register.ml b/src/plugins/pdg/register.ml index 4f707e7ffeb..ccce4b10491 100644 --- a/src/plugins/pdg/register.ml +++ b/src/plugins/pdg/register.ml @@ -20,104 +20,20 @@ (* *) (**************************************************************************) -let compute = Build.compute_pdg - -let pretty ?(bw=false) fmt pdg = - let kf = PdgTypes.Pdg.get_kf pdg in - Format.fprintf fmt "@[RESULT for %s:@]@\n@[ %a@]" - (Kernel_function.get_name kf) (PdgTypes.Pdg.pretty_bw ~bw) pdg - -let pretty_node short = - if short then PdgTypes.Node.pretty - else PdgTypes.Node.pretty_node - -let print_dot pdg filename = - PdgTypes.Pdg.build_dot filename pdg; - Pdg_parameters.feedback "dot file generated in %s" filename - -module Tbl = - Kernel_function.Make_Table - (PdgTypes.Pdg) - (struct - let name = "Pdg.State" - let dependencies = [] (* postponed because !Db.From.self may - not exist yet *) - let size = 17 - end) let () = Cmdline.run_after_extended_stage (fun () -> State_dependency_graph.add_codependencies - ~onto:Tbl.self + ~onto:Pdg_tbl.self [ !Db.From.self ]) -(** Register external functions into Db. *) -let () = - Db.Pdg.self := Tbl.self; - Db.Pdg.get := Tbl.memo compute; - Db.Pdg.node_key := PdgTypes.Node.elem_key; - - Db.Pdg.find_decl_var_node := Sets.find_decl_var_node; - Db.Pdg.find_entry_point_node := Sets.find_entry_point_node; - Db.Pdg.find_top_input_node := Sets.find_top_input_node; - Db.Pdg.find_simple_stmt_nodes := Sets.find_simple_stmt_nodes; - Db.Pdg.find_stmt_and_blocks_nodes := Sets.find_stmt_and_blocks_nodes; - Db.Pdg.find_stmt_node := Sets.find_stmt_node; - Db.Pdg.find_label_node := Sets.find_label_node; - Db.Pdg.find_location_nodes_at_stmt := Sets.find_location_nodes_at_stmt; - Db.Pdg.find_location_nodes_at_begin := Sets.find_location_nodes_at_begin; - Db.Pdg.find_location_nodes_at_end := Sets.find_location_nodes_at_end; - Db.Pdg.find_call_ctrl_node := Sets.find_call_ctrl_node; - Db.Pdg.find_call_input_node := Sets.find_call_num_input_node; - Db.Pdg.find_call_output_node := Sets.find_call_output_node; - Db.Pdg.find_input_node := Sets.find_input_node; - Db.Pdg.find_ret_output_node := Sets.find_output_node; - Db.Pdg.find_output_nodes := Sets.find_output_nodes; - Db.Pdg.find_all_inputs_nodes := Sets.find_all_input_nodes; - - Db.Pdg.find_call_stmts := Sets.find_call_stmts; - - Db.Pdg.find_code_annot_nodes := Annot.find_code_annot_nodes; - Db.Pdg.find_fun_precond_nodes := Annot.find_fun_precond_nodes; - Db.Pdg.find_fun_postcond_nodes := Annot.find_fun_postcond_nodes; - - Db.Pdg.find_call_out_nodes_to_select := Sets.find_call_out_nodes_to_select; - Db.Pdg.find_in_nodes_to_select_for_this_call := - Sets.find_in_nodes_to_select_for_this_call; - - Db.Pdg.direct_dpds := Sets.direct_dpds; - Db.Pdg.direct_ctrl_dpds := Sets.direct_ctrl_dpds; - Db.Pdg.direct_data_dpds := Sets.direct_data_dpds; - Db.Pdg.direct_addr_dpds := Sets.direct_addr_dpds; - - Db.Pdg.all_dpds := Sets.find_nodes_all_dpds; - Db.Pdg.all_ctrl_dpds := Sets.find_nodes_all_ctrl_dpds; - Db.Pdg.all_data_dpds := Sets.find_nodes_all_data_dpds; - Db.Pdg.all_addr_dpds := Sets.find_nodes_all_addr_dpds; - - Db.Pdg.direct_uses := Sets.direct_uses; - Db.Pdg.direct_ctrl_uses := Sets.direct_ctrl_uses; - Db.Pdg.direct_data_uses := Sets.direct_data_uses; - Db.Pdg.direct_addr_uses := Sets.direct_addr_uses; - - Db.Pdg.all_uses := Sets.all_uses; - - Db.Pdg.custom_related_nodes := Sets.custom_related_nodes; - - Db.Pdg.iter_nodes := PdgTypes.Pdg.iter_nodes; - - Db.Pdg.pretty := pretty ; - Db.Pdg.pretty_node := pretty_node ; - Db.Pdg.pretty_key := PdgIndex.Key.pretty; - Db.Pdg.extract := print_dot - (* This module contains polymorphic functions : cannot be registered in Db. Can be used through Pdg.Register instead (see Pdg.mli) *) include Marks let deps = - [!Db.Pdg.self; Pdg_parameters.BuildAll.self; Pdg_parameters.BuildFct.self] + [Pdg_tbl.self; Pdg_parameters.BuildAll.self; Pdg_parameters.BuildFct.self] let () = Pdg_parameters.BuildAll.set_output_dependencies deps @@ -130,11 +46,11 @@ let compute () = Eva.Analysis.compute (); let do_kf_pdg kf = if compute_for_kf kf then - let pdg = !Db.Pdg.get kf in + let pdg = Pdg_tbl.get kf in let dot_basename = Pdg_parameters.DotBasename.get () in if dot_basename <> "" then let fname = Kernel_function.get_name kf in - !Db.Pdg.extract pdg (dot_basename ^ "." ^ fname ^ ".dot") + Pdg_tbl.print_dot pdg (dot_basename ^ "." ^ fname ^ ".dot") in Callgraph.Uses.iter_in_rev_order do_kf_pdg; let pp_sep fmt () = Format.pp_print_string fmt "," in @@ -151,7 +67,7 @@ let output () = let bw = Pdg_parameters.PrintBw.get () in let do_kf_pdg kf = if compute_for_kf kf then - let pdg = !Db.Pdg.get kf in + let pdg = Pdg_tbl.get kf in let header fmt = Format.fprintf fmt "PDG for %a" Kernel_function.pretty kf in diff --git a/src/plugins/postdominators/print.ml b/src/plugins/postdominators/print.ml index 6ff5e94dd08..99549e4fb68 100644 --- a/src/plugins/postdominators/print.ml +++ b/src/plugins/postdominators/print.ml @@ -24,7 +24,7 @@ open Cil_types open Cil_datatype let pretty_stmt fmt s = - let key = PdgIndex.Key.stmt_key s in !Db.Pdg.pretty_key fmt key + let key = PdgIndex.Key.stmt_key s in PdgIndex.Key.pretty fmt key module Printer = struct diff --git a/src/plugins/scope/defs.ml b/src/plugins/scope/defs.ml index 2e7fbdbdf86..a73ef647869 100644 --- a/src/plugins/scope/defs.ml +++ b/src/plugins/scope/defs.ml @@ -60,19 +60,19 @@ let _pp_set prefix fmt = let rec add_callee_nodes z acc nodes = let new_nodes, acc = NSet.fold (fun node acc2 -> - match !Db.Pdg.node_key node with + match Pdg.Api.node_key node with | PdgIndex.Key.SigCallKey (cid, PdgIndex.Signature.Out out_key) -> let callees = Eva.Results.callee (PdgIndex.Key.call_from_id cid) in List.fold_left (fun (new_nodes, acc) kf -> - let callee_pdg = !Db.Pdg.get kf in + let callee_pdg = Pdg.Api.get kf in let outputs = match out_key with | PdgIndex.Signature.OutLoc out -> (* [out] might be an over-approximation of the location we are searching for. We refine the search if needed. *) let z = Locations.Zone.narrow out z in - fst (!Db.Pdg.find_location_nodes_at_end callee_pdg z) + fst (Pdg.Api.find_location_nodes_at_end callee_pdg z) | PdgIndex.Signature.OutRet -> (* probably never occurs *) - fst (!Db.Pdg.find_output_nodes callee_pdg out_key) + fst (Pdg.Api.find_output_nodes callee_pdg out_key) in let outputs = List.map fst outputs in add_list_to_set outputs new_nodes, add_list_to_set outputs acc) @@ -99,25 +99,25 @@ let rec add_caller_nodes z kf acc (undef, nodes) = | None -> acc_undef, acc | Some undef -> let nodes_for_undef, undef' = - !Db.Pdg.find_location_nodes_at_stmt pdg stmt ~before:true undef + Pdg.Api.find_location_nodes_at_stmt pdg stmt ~before:true undef in let acc_undef = join_undef acc_undef undef' in let acc = add_list_to_set (List.map fst nodes_for_undef) acc in acc_undef, acc in let add_call_input_nodes node (acc_undef, acc) = - match !Db.Pdg.node_key node with + match Pdg.Api.node_key node with | PdgIndex.Key.SigKey (PdgIndex.Signature.In in_key) -> begin match in_key with | PdgIndex.Signature.InCtrl -> (* We only look for the values *) acc_undef, acc | PdgIndex.Signature.InNum n_param -> - let n = !Db.Pdg.find_call_input_node pdg stmt n_param in + let n = Pdg.Api.find_call_input_node pdg stmt n_param in acc_undef, NSet.add n acc | PdgIndex.Signature.InImpl z' -> let z = Locations.Zone.narrow z z' in - let nodes, undef'= !Db.Pdg.find_location_nodes_at_stmt + let nodes, undef'= Pdg.Api.find_location_nodes_at_stmt pdg stmt ~before:true z in let acc_undef = join_undef acc_undef undef' in @@ -128,7 +128,7 @@ let rec add_caller_nodes z kf acc (undef, nodes) = NSet.fold add_call_input_nodes nodes (acc_undef, acc) in let add_one_caller_nodes acc (kf, stmts) = - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let acc_undef, caller_nodes = List.fold_left (add_one_call_nodes pdg) (None, NSet.empty) stmts in add_caller_nodes z kf (NSet.union caller_nodes acc) (acc_undef, caller_nodes) @@ -138,9 +138,9 @@ let compute_aux kf stmt zone = debug1 "[Defs.compute] for %a at sid:%d in '%a'@." Locations.Zone.pretty zone stmt.sid Kernel_function.pretty kf; try - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let nodes, undef = - !Db.Pdg.find_location_nodes_at_stmt pdg stmt ~before:true zone + Pdg.Api.find_location_nodes_at_stmt pdg stmt ~before:true zone in let nodes = add_list_to_set (List.map fst nodes) NSet.empty in let nodes = @@ -152,13 +152,13 @@ let compute_aux kf stmt zone = else nodes in Some (nodes, undef) - with Db.Pdg.Bottom | Db.Pdg.Top | Not_found -> + with Pdg.Api.Bottom | Pdg.Api.Top | Not_found -> None let compute kf stmt lval = let extract (nodes, undef) = let add_node node defs = - match PdgIndex.Key.stmt (!Db.Pdg.node_key node) with + match PdgIndex.Key.stmt (Pdg.Api.node_key node) with | None -> defs | Some s -> Stmt.Hptset.add s defs in @@ -185,7 +185,7 @@ let compute_with_def_type_zone kf stmt zone = let after = (direct || prev_d, indirect || pred_i) in Stmt.Map.add stmt after acc in - match !Db.Pdg.node_key node with + match Pdg.Api.node_key node with | PdgIndex.Key.Stmt s -> change s (true, false) | PdgIndex.Key.CallStmt _ -> assert false | PdgIndex.Key.SigCallKey (s, sign) -> diff --git a/src/plugins/scope/dune b/src/plugins/scope/dune index 95c81426d4f..82e4e62e600 100644 --- a/src/plugins/scope/dune +++ b/src/plugins/scope/dune @@ -27,6 +27,7 @@ (echo "Scope:" %{lib-available:frama-c-scope.core} "\n") (echo " - Eva:" %{lib-available:frama-c-eva.core} "\n") (echo " - Inout:" %{lib-available:frama-c-inout.core} "\n") + (echo " - Pdg:" %{lib-available:frama-c-pdg.core} "\n") ) ) ) @@ -36,7 +37,7 @@ (optional) (public_name frama-c-scope.core) (flags -open Frama_c_kernel :standard -w -9) - (libraries frama-c.kernel frama-c-eva.core frama-c-inout.core) + (libraries frama-c.kernel frama-c-eva.core frama-c-inout.core frama-c-pdg.core) ) (plugin (optional) (name scope) (libraries frama-c-scope.core) (site (frama-c plugins))) diff --git a/src/plugins/scope/zones.ml b/src/plugins/scope/zones.ml index aa02df158d8..bc98607ed33 100644 --- a/src/plugins/scope/zones.ml +++ b/src/plugins/scope/zones.ml @@ -262,7 +262,7 @@ let compute_ctrl_info pdg ctrl_part used_stmts = let module CtrlCompute = Dataflow2.Backwards(CtrlComputer) in let seen = Stmt.Hashtbl.create 50 in let rec add_node_ctrl_nodes new_stmts node = - let ctrl_nodes = !Db.Pdg.direct_ctrl_dpds pdg node in + let ctrl_nodes = Pdg.Api.direct_ctrl_dpds pdg node in List.fold_left add_ctrl_node new_stmts ctrl_nodes and add_ctrl_node new_stmts ctrl_node = debug2 "[zones] add ctrl node %a@." PdgTypes.Node.pretty ctrl_node; @@ -287,7 +287,7 @@ let compute_ctrl_info pdg ctrl_part used_stmts = if Stmt.Hashtbl.mem seen stmt then new_stmts else begin Stmt.Hashtbl.add seen stmt (); - match !Db.Pdg.find_simple_stmt_nodes pdg stmt with + match Pdg.Api.find_simple_stmt_nodes pdg stmt with | [] -> [] | n::_ -> add_node_ctrl_nodes new_stmts n end @@ -323,7 +323,7 @@ let compute kf stmt lval = let used_stmts = DataComputer.get_and_reset_used_stmts () in let all_used_stmts = if used_stmts = [] then [] - else compute_ctrl_info (!Db.Pdg.get kf) ctrl_part used_stmts + else compute_ctrl_info (Pdg.Api.get kf) ctrl_part used_stmts in let all_used_stmts = List.fold_left diff --git a/src/plugins/security_slicing/components.ml b/src/plugins/security_slicing/components.ml index 629fa05f383..1b76f3467bb 100644 --- a/src/plugins/security_slicing/components.ml +++ b/src/plugins/security_slicing/components.ml @@ -98,7 +98,7 @@ let search_security_requirements () = open PdgIndex -let get_node_stmt node = Key.stmt (!Db.Pdg.node_key node) +let get_node_stmt node = Key.stmt (Pdg.Api.node_key node) module NodeKf = Datatype.Pair(PdgTypes.Node)(Kernel_function) @@ -246,26 +246,26 @@ module Todolist : sig type todo = private { node: PdgTypes.Node.t; kf: kernel_function; - pdg: Db.Pdg.t; + pdg: Pdg.Api.t; callstack_length: int; from_deep: bool } type t = todo list - val mk_init: kernel_function -> Db.Pdg.t -> PdgTypes.Node.t list -> todo list + val mk_init: kernel_function -> Pdg.Api.t -> PdgTypes.Node.t list -> todo list val add: - PdgTypes.Node.t -> kernel_function -> Db.Pdg.t -> int -> bool -> t -> t + PdgTypes.Node.t -> kernel_function -> Pdg.Api.t -> int -> bool -> t -> t end = struct type todo = { node: PdgTypes.Node.t; kf: kernel_function; - pdg: Db.Pdg.t; + pdg: Pdg.Api.t; callstack_length: int; from_deep: bool } type t = todo list let add n kf pdg len fd list = - match !Db.Pdg.node_key n with + match Pdg.Api.node_key n with | Key.SigKey (Signature.In Signature.InCtrl) -> (* do not consider node [InCtrl] *) list @@ -276,7 +276,7 @@ end = struct list | _ -> Security_slicing_parameters.debug ~level:2 "adding node %a (in %s)" - (!Db.Pdg.pretty_node false) n + (Pdg.Api.pretty_node false) n (Kernel_function.get_name kf); { node = n; kf = kf; pdg = pdg; callstack_length = len; from_deep = fd } @@ -301,7 +301,7 @@ module Component = struct | Forward of fwd_kind type value = - { pdg: Db.Pdg.t; + { pdg: Pdg.Api.t; mutable callstack_length: int; mutable direct: bool; mutable indirect_backward: bool; @@ -356,15 +356,15 @@ module Component = struct (* do not consider address dependencies now (except for impact analysis): just consider them during the last slicing pass (for semantic preservation of pointers) *) - let direct node = !Db.Pdg.direct_data_dpds pdg node in + let direct node = Pdg.Api.direct_data_dpds pdg node in match kind with | Direct -> direct node - | Indirect_Backward -> direct node @ !Db.Pdg.direct_ctrl_dpds pdg node + | Indirect_Backward -> direct node @ Pdg.Api.direct_ctrl_dpds pdg node | Forward Security -> - !Db.Pdg.direct_data_uses pdg node @ !Db.Pdg.direct_ctrl_uses pdg node + Pdg.Api.direct_data_uses pdg node @ Pdg.Api.direct_ctrl_uses pdg node | Forward Impact -> - !Db.Pdg.direct_data_uses pdg node @ !Db.Pdg.direct_ctrl_uses pdg node - @ !Db.Pdg.direct_addr_uses pdg node + Pdg.Api.direct_data_uses pdg node @ Pdg.Api.direct_ctrl_uses pdg node + @ Pdg.Api.direct_addr_uses pdg node let search_input kind kf lazy_l = try @@ -378,18 +378,18 @@ module Component = struct [] let add_from_deep caller todo n = - Todolist.add n caller (!Db.Pdg.get caller) 0 true todo + Todolist.add n caller (Pdg.Api.get caller) 0 true todo let forward_caller kf node todolist = - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in List.fold_left (fun todolist (caller, callsites) -> (* foreach caller *) List.fold_left (fun todolist callsite -> let nodes = - !Db.Pdg.find_call_out_nodes_to_select - pdg (PdgTypes.NodeSet.singleton node) (!Db.Pdg.get caller) callsite + Pdg.Api.find_call_out_nodes_to_select + pdg (PdgTypes.NodeSet.singleton node) (Pdg.Api.get caller) callsite in List.fold_left (add_from_deep caller) @@ -420,7 +420,7 @@ module Component = struct end else begin Security_slicing_parameters.debug ~level:2 "considering node %a (in %s)" - (!Db.Pdg.pretty_node false) node + (Pdg.Api.pretty_node false) node (Kernel_function.get_name kf); (* intraprocedural related_nodes *) let related_nodes = one_step_related_nodes kind pdg node in @@ -448,7 +448,7 @@ module Component = struct for zone %a@." (Kernel_function.get_name kf) (Kernel_function.get_name caller) Locations.Zone.pretty zone;*) - let pdg_caller = !Db.Pdg.get caller in + let pdg_caller = Pdg.Api.get caller in let do_call todolist callsite = match kind with | Direct | Indirect_Backward -> @@ -465,13 +465,13 @@ module Component = struct todolist in let todolist = - match !Db.Pdg.node_key node with + match Pdg.Api.node_key node with | Key.SigKey (Signature.In Signature.InCtrl) -> assert false | Key.SigKey (Signature.In (Signature.InImpl zone)) -> let compute_nodes pdg_caller callsite = let nodes, _undef_zone = - !Db.Pdg.find_location_nodes_at_stmt + Pdg.Api.find_location_nodes_at_stmt pdg_caller callsite ~before:true zone (* TODO : use undef_zone (see FS#201)? *) in @@ -484,9 +484,9 @@ module Component = struct let compute_nodes pdg_caller callsite = [ match key with | Signature.In (Signature.InNum n) -> - !Db.Pdg.find_call_input_node pdg_caller callsite n + Pdg.Api.find_call_input_node pdg_caller callsite n | Signature.Out Signature.OutRet -> - !Db.Pdg.find_call_output_node pdg_caller callsite + Pdg.Api.find_call_output_node pdg_caller callsite | Signature.In (Signature.InCtrl | Signature.InImpl _) | Signature.Out _ -> @@ -511,14 +511,14 @@ module Component = struct "[security] search inside %s (from %s)@." (Kernel_function.get_name called_kf) (Kernel_function.get_name kf);*) - let called_pdg = !Db.Pdg.get called_kf in + let called_pdg = Pdg.Api.get called_kf in let nodes = try match kind, key with | (Direct | Indirect_Backward), Signature.Out out_key -> let nodes, _undef_zone = - !Db.Pdg.find_output_nodes called_pdg out_key + Pdg.Api.find_output_nodes called_pdg out_key (* TODO: use undef_zone (see FS#201) *) in let nodes = @@ -527,28 +527,28 @@ module Component = struct nodes | _, Signature.In (Signature.InNum n) -> search_input kind called_kf - (lazy [!Db.Pdg.find_input_node called_pdg n]) + (lazy [Pdg.Api.find_input_node called_pdg n]) | _, Signature.In Signature.InCtrl -> search_input kind called_kf (lazy - [!Db.Pdg.find_entry_point_node called_pdg]) + [Pdg.Api.find_entry_point_node called_pdg]) | _, Signature.In (Signature.InImpl _) -> assert false | Forward _, Signature.Out _ -> [] with - | Db.Pdg.Top -> + | Pdg.Api.Top -> Security_slicing_parameters.warning "no precise pdg for function %s. \n\ Ignoring this function in the analysis (potentially incorrect results)." (Kernel_function.get_name called_kf); [] - | Db.Pdg.Bottom | Not_found -> assert false + | Pdg.Api.Bottom | Not_found -> assert false in List.fold_left (fun todo n -> (*Format.printf "node %a inside %s@." - (!Db.Pdg.pretty_node false) n + (Pdg.Api.pretty_node false) n (Kernel_function.get_name called_kf);*) Todolist.add n called_kf called_pdg @@ -584,16 +584,16 @@ module Component = struct let from_stmt = List.fold_left (fun s n -> PdgTypes.NodeSet.add n s) PdgTypes.NodeSet.empty from_stmt in - let called_pdg = !Db.Pdg.get called_kf in + let called_pdg = Pdg.Api.get called_kf in let nodes = try - !Db.Pdg.find_in_nodes_to_select_for_this_call + Pdg.Api.find_in_nodes_to_select_for_this_call pdg from_stmt stmt called_pdg with - | Db.Pdg.Top -> + | Pdg.Api.Top -> (* warning already emitted in the previous fold *) [] - | Db.Pdg.Bottom | Not_found -> assert false + | Pdg.Api.Bottom | Not_found -> assert false in List.fold_left (fun todo n -> @@ -623,10 +623,10 @@ module Component = struct let initial_nodes kf stmt = Security_slicing_parameters.debug ~level:3 "computing initial nodes for %d" stmt.sid; - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let nodes = if Eva.Results.is_reachable stmt then - try !Db.Pdg.find_simple_stmt_nodes pdg stmt + try Pdg.Api.find_simple_stmt_nodes pdg stmt with Not_found -> assert false else begin Security_slicing_parameters.debug @@ -654,7 +654,7 @@ module Component = struct nodes in res - with Db.Pdg.Top | Db.Pdg.Bottom -> + with Pdg.Api.Top | Pdg.Api.Bottom -> Security_slicing_parameters.warning "PDG is not manageable. skipping."; M.empty @@ -665,7 +665,7 @@ module Component = struct Security_slicing_parameters.debug "computing backward indirect component for %d" stmt.sid; related_nodes_of_nodes Indirect_Backward res nodes - with Db.Pdg.Top | Db.Pdg.Bottom -> + with Pdg.Api.Top | Pdg.Api.Bottom -> Security_slicing_parameters.warning "PDG is not manageable. skipping."; M.empty @@ -855,7 +855,7 @@ let slice ctrl = let slicing = !Slicing.Project.mk_project name in let select (n, kf) sel = Security_slicing_parameters.debug ~level:2 "selecting %a (of %s)" - (!Db.Pdg.pretty_node false) n + (Pdg.Api.pretty_node false) n (Kernel_function.get_name kf); !Slicing.Select.select_pdg_nodes sel diff --git a/src/plugins/security_slicing/dune b/src/plugins/security_slicing/dune index 91009d8a819..4e24b20cfd4 100644 --- a/src/plugins/security_slicing/dune +++ b/src/plugins/security_slicing/dune @@ -26,6 +26,7 @@ (action (progn (echo "Security Slicing:" %{lib-available:frama-c-security_slicing.core} "\n") (echo " - Eva:" %{lib-available:frama-c-eva.core} "\n") + (echo " - Pdg:" %{lib-available:frama-c-pdg.core} "\n") ) ) ) @@ -35,7 +36,7 @@ (optional) (public_name frama-c-security_slicing.core) (flags -open Frama_c_kernel :standard -w -9) - (libraries frama-c.kernel frama-c-eva.core) + (libraries frama-c.kernel frama-c-eva.core frama-c-pdg.core) ) (plugin (optional) (name security_slicing) (libraries frama-c-security_slicing.core) (site (frama-c plugins))) diff --git a/src/plugins/slicing/fct_slice.ml b/src/plugins/slicing/fct_slice.ml index b470412386a..0a25e41fe18 100644 --- a/src/plugins/slicing/fct_slice.ml +++ b/src/plugins/slicing/fct_slice.ml @@ -356,7 +356,7 @@ end = struct let merge ff1 ff2 = let pdg1, fm1 = ff1.SlicingInternals.ff_marks in let pdg2, fm2 = ff2.SlicingInternals.ff_marks in - assert (Db.Pdg.from_same_fun pdg1 pdg2) ; + assert (Pdg.Api.from_same_fun pdg1 pdg2) ; let merge_marks m1 m2 = SlicingMarks.merge_marks [m1; m2] in let merge_call_info _c1 _c2 = None in let fm = PdgIndex.FctIndex.merge fm1 fm2 merge_marks merge_call_info in @@ -418,7 +418,7 @@ end = struct let m2m s m = let key = match s with | PdgMarks.SelIn loc -> PdgIndex.Key.implicit_in_key loc - | PdgMarks.SelNode (n,_z) -> !Db.Pdg.node_key n + | PdgMarks.SelNode (n,_z) -> Pdg.Api.node_key n in let old_m = get_mark old_marks key in let add_mark = @@ -436,7 +436,7 @@ end = struct SlicingParameters.debug ~level:2 "[Fct_Slice.FctMarks.marks_for_caller_inputs] for %a : \ old=%a new=%a -> %a" - !Db.Pdg.pretty_key key SlicingMarks.pretty_mark old_m + Pdg.Api.pretty_key key SlicingMarks.pretty_mark old_m SlicingMarks.pretty_mark m SlicingMarks.pretty_mark (match new_m with None -> SlicingMarks.bottom_mark | Some m -> m); @@ -467,7 +467,7 @@ end = struct let pdg = SlicingMacros.get_ff_pdg ff_call in let spare = SlicingMarks.mk_gen_spare in let rec add2 marks n = - match !Db.Pdg.node_key n with + match Pdg.Api.node_key n with | PdgIndex.Key.SigCallKey (_, (PdgIndex.Signature.In _)) -> marks | PdgIndex.Key.SigCallKey (_, (PdgIndex.Signature.Out key)) -> @@ -497,7 +497,7 @@ end = struct * it has already been taken into account in the "from". *) None | PdgMarks.SelNode (n, _z_opt) -> - let nkey = !Db.Pdg.node_key n in + let nkey = Pdg.Api.node_key n in (* let nkey = match z_opt with None -> nkey | Some z -> match nkey with @@ -516,7 +516,7 @@ end = struct | _ -> (); false in SlicingParameters.debug ~level:2 "[Fct_Slice.FctMarks.check_called_marks] for %a : old=%a new=%a -> %a %s" - !Db.Pdg.pretty_key nkey + Pdg.Api.pretty_key nkey SlicingMarks.pretty_mark old_m SlicingMarks.pretty_mark m SlicingMarks.pretty_mark @@ -532,7 +532,7 @@ end = struct SlicingParameters.debug ~level:2 "[Fct_Slice.FctMarks.persistent_in_marks_to_prop] from %s" (SlicingMacros.fi_name fi); let m2m _call _pdg_caller _n m = (* SlicingParameters.debug ~level:2 " in_m2m %a in %s ?@." - PdgIndex.Key.pretty (!Db.Pdg.node_key n) (SlicingMacros.pdg_name pdg_caller); *) + PdgIndex.Key.pretty (Pdg.Api.node_key n) (SlicingMacros.pdg_name pdg_caller); *) SlicingMarks.missing_input_mark ~call:SlicingMarks.bottom_mark ~called:m in let pdg = SlicingMacros.get_fi_pdg fi in @@ -546,13 +546,13 @@ end = struct let nkey = match n with | PdgMarks.SelNode (n, _z_opt) -> (* TODO : something to do for z_opt ? *) - !Db.Pdg.node_key n + Pdg.Api.node_key n | PdgMarks.SelIn l -> PdgIndex.Key.implicit_in_key l in let oldm = get_mark fm nkey in let newm = SlicingMarks.minus_marks m oldm in (* Format.printf "get_new_marks for %a : old=%a new=%a -> %a@." - !Db.Pdg.pretty_key nkey SlicingMarks.pretty_mark oldm + Pdg.Api.pretty_key nkey SlicingMarks.pretty_mark oldm SlicingMarks.pretty_mark m SlicingMarks.pretty_mark newm; *) if not (SlicingMarks.is_bottom_mark newm) then (n, newm)::acc else acc in List.fold_left add_if_new [] nodes_marks @@ -571,7 +571,7 @@ end = struct let mark_spare_call_nodes ff call = let pdg = SlicingMacros.get_ff_pdg ff in - let nodes = !Db.Pdg.find_simple_stmt_nodes pdg call in + let nodes = Pdg.Api.find_simple_stmt_nodes pdg call in mark_spare_nodes ff nodes (** TODO : @@ -587,8 +587,8 @@ end = struct let rec check_in_params n params = match params with | [] -> [] | _ :: params -> - let node = !Db.Pdg.find_input_node pdg n in - let dpds = !Db.Pdg.direct_dpds pdg node in + let node = Pdg.Api.find_input_node pdg n in + let dpds = Pdg.Api.direct_dpds pdg node in let get_n_mark n = get_mark ff_marks (PdgTypes.Node.elem_key n) in let dpds_marks = List.map get_n_mark dpds in let m = SlicingMarks.inter_marks dpds_marks in @@ -596,7 +596,7 @@ end = struct if not (SlicingMarks.is_bottom_mark m) then begin SlicingKernel.debug ~level:2 "[Fct_Slice.FctMarks.mark_visible_inputs] %a -> %a" - (!Db.Pdg.pretty_node true) node SlicingMarks.pretty_mark m; + (Pdg.Api.pretty_node true) node SlicingMarks.pretty_mark m; PdgMarks.add_node_to_select marks (node, None) m end else marks @@ -609,15 +609,15 @@ end = struct let mark_visible_output ff_marks = let pdg, _ = ff_marks in try - let out_node = !Db.Pdg.find_ret_output_node pdg in - let dpds = !Db.Pdg.direct_dpds pdg out_node in + let out_node = Pdg.Api.find_ret_output_node pdg in + let dpds = Pdg.Api.direct_dpds pdg out_node in let get_n_mark n = get_mark ff_marks (PdgTypes.Node.elem_key n) in let dpds_marks = List.map get_n_mark dpds in let m = SlicingMarks.inter_marks dpds_marks in if not (SlicingMarks.is_bottom_mark m) then begin SlicingParameters.debug ~level:2 "[Fct_Slice.FctMarks.mark_visible_outputs] %a -> %a" - (!Db.Pdg.pretty_node true) out_node SlicingMarks.pretty_mark m; + (Pdg.Api.pretty_node true) out_node SlicingMarks.pretty_mark m; let select = PdgMarks.add_node_to_select [] (out_node, None) m in let to_prop = mark_and_propagate ff_marks select in assert (to_prop = PropMark.empty_to_prop); () @@ -634,10 +634,10 @@ end = struct with PdgIndex.CallStatement -> assert false with Not_found -> SlicingMarks.bottom_mark in - Format.fprintf fmt "%a : %a" (!Db.Pdg.pretty_node true) node + Format.fprintf fmt "%a : %a" (Pdg.Api.pretty_node true) node SlicingMarks.pretty_mark m in - !Db.Pdg.iter_nodes print_node pdg + Pdg.Api.iter_nodes print_node pdg let debug_marked_ff fmt ff = Format.fprintf fmt "@[<hv>Print slice =@ %s@]" (SlicingMacros.ff_name ff); @@ -663,7 +663,7 @@ let get_called_slice ff call = let _pretty_node_marks fmt marks = let print fmt (n, m) = - (!Db.Pdg.pretty_node true) fmt n; SlicingMarks.pretty_mark fmt m + (Pdg.Api.pretty_node true) fmt n; SlicingMarks.pretty_mark fmt m in Format.fprintf fmt "%a" (fun fmt x -> List.iter (print fmt) x) marks @@ -1000,7 +1000,7 @@ let get_call_in_nodes called_kf call_info called_in_zone = let _, nodes, in_zone = List.fold_left check_param (1, [], called_in_zone) param_list in - let impl_in_nodes, undef = !Db.Pdg.find_location_nodes_at_stmt + let impl_in_nodes, undef = Pdg.Api.find_location_nodes_at_stmt pdg_caller call_stmt ~before:true in_zone in (nodes @ impl_in_nodes), undef @@ -1232,7 +1232,7 @@ let apply_missing_inputs ff call missing_inputs = assert (not (SlicingMarks.is_bottom_mark m)); match sel with | PdgMarks.SelNode (n, _) - when (!Db.Pdg.node_key n = PdgIndex.Key.top_input) -> true + when (Pdg.Api.node_key n = PdgIndex.Key.top_input) -> true | _ -> visible_top tl in let is_top_visible = visible_top input_marks in *) diff --git a/src/plugins/slicing/printSlice.ml b/src/plugins/slicing/printSlice.ml index faa275ee37b..1775db3293c 100644 --- a/src/plugins/slicing/printSlice.ml +++ b/src/plugins/slicing/printSlice.ml @@ -334,7 +334,7 @@ let build_dot_project filename title = let print_fct_stmts fmt kf = try - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in print_fct_from_pdg fmt pdg; Format.pp_print_flush fmt () with Not_found -> () diff --git a/src/plugins/slicing/slicingActions.ml b/src/plugins/slicing/slicingActions.ml index 3529e422015..8fd243d8a96 100644 --- a/src/plugins/slicing/slicingActions.ml +++ b/src/plugins/slicing/slicingActions.ml @@ -156,10 +156,10 @@ let mk_appli_select_calls fi = SlicingInternals.CrAppli (SlicingInternals.CaCall let mk_crit_mark_calls fi_caller to_call mark = let select = try let caller = SlicingMacros.get_fi_kf fi_caller in - let pdg_caller = !Db.Pdg.get caller in - let call_stmts = !Db.Pdg.find_call_stmts ~caller to_call in + let pdg_caller = Pdg.Api.get caller in + let call_stmts = Pdg.Api.find_call_stmts ~caller to_call in let stmt_mark stmt = - let stmt_ctrl_node = !Db.Pdg.find_call_ctrl_node pdg_caller stmt in + let stmt_ctrl_node = Pdg.Api.find_call_ctrl_node pdg_caller stmt in (PdgMarks.mk_select_node stmt_ctrl_node, mark) in let select = List.map stmt_mark call_stmts in @@ -182,7 +182,7 @@ let mk_crit_add_output_marks ff select = (* let mk_crit_add_all_outputs_mark ff mark = let pdg = SlicingMacros.get_ff_pdg ff in - let nodes = !Db.Pdg.find_all_outputs_nodes pdg in + let nodes = Pdg.Api.find_all_outputs_nodes pdg in let nd_m = build_simple_node_selection mark in let select = mk_mark_nodes nodes nd_m in mk_ff_user_crit ff select @@ -206,7 +206,7 @@ let rec print_nd_and_mark_list fmt ndm_list = print_nd_and_mark fmt x; print_nd_and_mark_list fmt ndm_list let print_nodes fmt nodes = - let print n = Format.fprintf fmt "%a " (!Db.Pdg.pretty_node true) n in + let print n = Format.fprintf fmt "%a " (Pdg.Api.pretty_node true) n in List.iter print nodes let print_node_mark fmt n z m = diff --git a/src/plugins/slicing/slicingActions.mli b/src/plugins/slicing/slicingActions.mli index 975252aaa93..314a61918cb 100644 --- a/src/plugins/slicing/slicingActions.mli +++ b/src/plugins/slicing/slicingActions.mli @@ -43,7 +43,7 @@ val build_node_and_dpds_selection : ?nd_marks:n_or_d_marks -> sl_mark -> n_or_d_marks val translate_crit_to_select : - Db.Pdg.t -> ?to_select:select -> + Pdg.Api.t -> ?to_select:select -> ((PdgTypes.Node.t * Locations.Zone.t option) list * n_or_d_marks) list -> select diff --git a/src/plugins/slicing/slicingMacros.ml b/src/plugins/slicing/slicingMacros.ml index d221c7299c3..05df109b352 100644 --- a/src/plugins/slicing/slicingMacros.ml +++ b/src/plugins/slicing/slicingMacros.ml @@ -127,7 +127,7 @@ let get_pdg_kf pdg = PdgTypes.Pdg.get_kf pdg (** {4 getting PDG} *) -let get_fi_pdg fi = let kf = get_fi_kf fi in !Db.Pdg.get kf +let get_fi_pdg fi = let kf = get_fi_kf fi in Pdg.Api.get kf let get_ff_pdg ff = get_fi_pdg ff.SlicingInternals.ff_fct diff --git a/src/plugins/slicing/slicingMacros.mli b/src/plugins/slicing/slicingMacros.mli index 04e20ee753e..183aff57436 100644 --- a/src/plugins/slicing/slicingMacros.mli +++ b/src/plugins/slicing/slicingMacros.mli @@ -40,8 +40,8 @@ val ff_src_name : fct_slice -> string val get_fi_kf : fct_info -> Cil_types.kernel_function val get_ff_kf : fct_slice -> Cil_types.kernel_function val get_pdg_kf : PdgTypes.Pdg.t -> Kernel_function.t -val get_fi_pdg : fct_info -> Db.Pdg.t -val get_ff_pdg : fct_slice -> Db.Pdg.t +val get_fi_pdg : fct_info -> Pdg.Api.t +val get_ff_pdg : fct_slice -> Pdg.Api.t val ff_slicing_level : fct_slice -> level_option val change_fi_slicing_level : fct_info -> level_option -> unit val change_slicing_level : Kernel_function.t -> int -> unit diff --git a/src/plugins/slicing/slicingSelect.ml b/src/plugins/slicing/slicingSelect.ml index 25b922ab7f4..4b3c23c2913 100644 --- a/src/plugins/slicing/slicingSelect.ml +++ b/src/plugins/slicing/slicingSelect.ml @@ -72,7 +72,7 @@ let basic_add_select kf select nodes ?(undef) nd_marks = match sel with | SlicingInternals.CuTop _ -> select | SlicingInternals.CuSelect sel -> - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let nodes = List.map (fun n -> (n, None) (*TODO: add z_part ? *)) nodes in (* let nd_marks = SlicingActions.build_node_and_dpds_selection mark in *) @@ -89,7 +89,7 @@ let select_pdg_nodes kf ?(select=empty_db_select kf) nodes mark = SlicingParameters.debug ~level:1 "[Register.select_pdg_nodes]" ; let nd_marks = SlicingActions.build_node_and_dpds_selection mark in try basic_add_select kf select nodes nd_marks - with Db.Pdg.Top | Db.Pdg.Bottom -> + with Pdg.Api.Top | Pdg.Api.Bottom -> assert false (* if we have node, we must have a pdg somewhere ! *) let mk_select pdg sel nodes undef mark = @@ -120,9 +120,9 @@ let select_stmt_zone kf ?(select=empty_db_select kf) stmt ~before loc mark = | SlicingInternals.CuTop _ -> select | SlicingInternals.CuSelect sel -> try - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let nodes, undef = - !Db.Pdg.find_location_nodes_at_stmt pdg stmt ~before loc in + Pdg.Api.find_location_nodes_at_stmt pdg stmt ~before loc in let sel = mk_select pdg sel nodes undef mark in (fvar, sel) with @@ -138,8 +138,8 @@ let select_stmt_zone kf ?(select=empty_db_select kf) stmt ~before loc mark = (if before then "before" else "after") stmt.sid Kernel_function.pretty kf; select - | Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; select + | Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; select (** this one is similar to [select_stmt_zone] with the return statement @@ -154,10 +154,10 @@ let select_in_out_zone ~at_end ~use_undef kf select loc mark = | SlicingInternals.CuTop _ -> select | SlicingInternals.CuSelect sel -> try - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let find = - if at_end then !Db.Pdg.find_location_nodes_at_end - else !Db.Pdg.find_location_nodes_at_begin in + if at_end then Pdg.Api.find_location_nodes_at_end + else Pdg.Api.find_location_nodes_at_begin in let nodes, undef = find pdg loc in let undef = if use_undef then undef else None in let sel = mk_select pdg sel nodes undef mark in @@ -169,8 +169,8 @@ let select_in_out_zone ~at_end ~use_undef kf select loc mark = Locations.Zone.pretty loc SlicingMarks.pretty_mark mark (if at_end then "end" else "begin") Kernel_function.pretty kf; select - | Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; select + | Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; select let select_zone_at_end kf ?(select=empty_db_select kf) loc mark = select_in_out_zone ~at_end:true ~use_undef:true kf select loc mark @@ -183,9 +183,9 @@ let select_zone_at_entry kf ?(select=empty_db_select kf) loc mark = let stmt_nodes_to_select pdg stmt = try - let stmt_nodes = !Db.Pdg.find_stmt_and_blocks_nodes pdg stmt in + let stmt_nodes = Pdg.Api.find_stmt_and_blocks_nodes pdg stmt in SlicingParameters.debug ~level:2 "[Register.stmt_nodes_to_select] results on stmt %d (%a)" stmt.sid - (fun fmt l -> List.iter (!Db.Pdg.pretty_node true fmt) l) + (fun fmt l -> List.iter (Pdg.Api.pretty_node true fmt) l) stmt_nodes; stmt_nodes with Not_found -> @@ -203,23 +203,23 @@ let select_stmt_computation kf ?(select=empty_db_select kf) stmt mark = end else try - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let stmt_nodes = stmt_nodes_to_select pdg stmt in let nd_marks = SlicingActions.build_node_and_dpds_selection mark in basic_add_select kf select stmt_nodes nd_marks - with Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; select + with Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; select let select_label kf ?(select=empty_db_select kf) label mark = SlicingParameters.debug ~level:1 "[Register.select_label] on label " (* Logic_label.pretty label *); try - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let nodes = let add_label_nodes l acc = match l with | StmtLabel stmt -> let add acc l = - try !Db.Pdg.find_label_node pdg !stmt l :: acc + try Pdg.Api.find_label_node pdg !stmt l :: acc with Not_found -> acc in List.fold_left add acc (!stmt).labels @@ -230,8 +230,8 @@ let select_label kf ?(select=empty_db_select kf) label mark = in let nd_marks = SlicingActions.build_node_and_dpds_selection mark in basic_add_select kf select nodes nd_marks - with Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; select + with Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; select (** marking a call node means that a [choose_call] will have to decide that to * call according to the slicing-level, but anyway, the call will be visible. @@ -239,42 +239,42 @@ let select_label kf ?(select=empty_db_select kf) label mark = let select_minimal_call kf ?(select=empty_db_select kf) stmt m = SlicingParameters.debug ~level:1 "[Register.select_minimal_call]"; try - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in let call = check_call stmt true in - let call_node = !Db.Pdg.find_call_ctrl_node pdg call in + let call_node = Pdg.Api.find_call_ctrl_node pdg call in let nd_marks = SlicingActions.build_simple_node_selection m in basic_add_select kf select [call_node] nd_marks - with Db.Pdg.Top -> top_db_select kf m - | Db.Pdg.Bottom -> bottom_msg kf; select + with Pdg.Api.Top -> top_db_select kf m + | Pdg.Api.Bottom -> bottom_msg kf; select let select_stmt_ctrl kf ?(select=empty_db_select kf) stmt = SlicingParameters.debug ~level:1 "[Register.select_stmt_ctrl] of sid:%d" stmt.sid; let mark = SlicingMarks.mk_user_mark ~ctrl:true ~data:false ~addr:false in try - let pdg = !Db.Pdg.get kf in - let stmt_nodes = !Db.Pdg.find_simple_stmt_nodes pdg stmt in + let pdg = Pdg.Api.get kf in + let stmt_nodes = Pdg.Api.find_simple_stmt_nodes pdg stmt in let nd_marks = SlicingActions.build_ctrl_dpds_selection mark in basic_add_select kf select stmt_nodes nd_marks - with Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; empty_db_select kf + with Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; empty_db_select kf let select_entry_point kf ?(select=empty_db_select kf) mark = SlicingParameters.debug ~level:1 "[Register.select_entry_point] of %a" Kernel_function.pretty kf; try - let pdg = !Db.Pdg.get kf in - let node = !Db.Pdg.find_entry_point_node pdg in + let pdg = Pdg.Api.get kf in + let node = Pdg.Api.find_entry_point_node pdg in let nd_marks = SlicingActions.build_simple_node_selection mark in basic_add_select kf select [node] nd_marks - with Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; empty_db_select kf + with Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; empty_db_select kf let select_return kf ?(select=empty_db_select kf) mark = SlicingParameters.debug ~level:1 "[Register.select_return] of %a" Kernel_function.pretty kf; try - let pdg = !Db.Pdg.get kf in - let node = !Db.Pdg.find_ret_output_node pdg in + let pdg = Pdg.Api.get kf in + let node = Pdg.Api.find_ret_output_node pdg in let nd_marks = SlicingActions.build_simple_node_selection mark in basic_add_select kf select [node] nd_marks with @@ -283,8 +283,8 @@ let select_return kf ?(select=empty_db_select kf) mark = "@[Nothing to select for return stmt of %a@]" Kernel_function.pretty kf; select - | Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; empty_db_select kf + | Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; empty_db_select kf let select_decl_var kf ?(select=empty_db_select kf) vi mark = SlicingParameters.debug ~level:1 "[Register.select_decl_var] of %s in %a@." @@ -292,8 +292,8 @@ let select_decl_var kf ?(select=empty_db_select kf) vi mark = if vi.Cil_types.vglob (* no slicing request on globals *) then select else try - let pdg = !Db.Pdg.get kf in - let node = !Db.Pdg.find_decl_var_node pdg vi in + let pdg = Pdg.Api.get kf in + let node = Pdg.Api.find_decl_var_node pdg vi in let nd_marks = SlicingActions.build_simple_node_selection mark in basic_add_select kf select [node] nd_marks with @@ -302,8 +302,8 @@ let select_decl_var kf ?(select=empty_db_select kf) vi mark = "@[Nothing to select for %s declarationin %a@]" vi.Cil_types.vname Kernel_function.pretty kf; select - | Db.Pdg.Top -> top_db_select kf mark - | Db.Pdg.Bottom -> bottom_msg kf; empty_db_select kf + | Pdg.Api.Top -> top_db_select kf mark + | Pdg.Api.Bottom -> bottom_msg kf; empty_db_select kf let merge_select select1 select2 = @@ -351,7 +351,7 @@ let add_crit_ff_change_call ff_caller call f_to_call = let call_ff_in_caller ~caller ~to_call = let kf_caller = SlicingMacros.get_ff_kf caller in let kf_to_call = SlicingMacros.get_ff_kf to_call in - let call_stmts = !Db.Pdg.find_call_stmts ~caller:kf_caller kf_to_call in + let call_stmts = Pdg.Api.find_call_stmts ~caller:kf_caller kf_to_call in let ff_to_call = SlicingInternals.CallSlice to_call in let add_change_call stmt = add_crit_ff_change_call caller stmt ff_to_call ; @@ -367,7 +367,7 @@ let call_fsrc_in_caller ~caller ~to_call = let kf_caller = SlicingMacros.get_ff_kf caller in let fi_to_call = SlicingMacros.get_kf_fi to_call in let kf_to_call = SlicingMacros.get_fi_kf fi_to_call in - let call_stmts = !Db.Pdg.find_call_stmts ~caller:kf_caller kf_to_call in + let call_stmts = Pdg.Api.find_call_stmts ~caller:kf_caller kf_to_call in let add_change_call stmt = add_crit_ff_change_call caller stmt (SlicingInternals.CallSrc (Some fi_to_call)) in List.iter add_change_call call_stmts @@ -375,9 +375,9 @@ let call_fsrc_in_caller ~caller ~to_call = let call_min_f_in_caller ~caller ~to_call = let kf_caller = SlicingMacros.get_ff_kf caller in let pdg = SlicingMacros.get_ff_pdg caller in - let call_stmts = !Db.Pdg.find_call_stmts ~caller:kf_caller to_call in + let call_stmts = Pdg.Api.find_call_stmts ~caller:kf_caller to_call in let call_nodes = - List.map (fun call -> (!Db.Pdg.find_call_ctrl_node pdg call),None) + List.map (fun call -> (Pdg.Api.find_call_ctrl_node pdg call),None) call_stmts in let m = SlicingMarks.mk_user_spare in let nd_marks = SlicingActions.build_simple_node_selection m in @@ -389,7 +389,7 @@ let is_already_selected ff db_select = match select with | SlicingInternals.CuTop _ -> assert false | SlicingInternals.CuSelect to_select -> - (* let pdg = !Db.Pdg.get (Globals.Functions.get fvar) in *) + (* let pdg = Pdg.Api.get (Globals.Functions.get fvar) in *) let new_marks = Fct_slice.filter_already_in ff to_select in let ok = if new_marks = [] then true else false in if ok then diff --git a/src/plugins/slicing/slicingSelect.mli b/src/plugins/slicing/slicingSelect.mli index c139085e9da..6f682ad2735 100644 --- a/src/plugins/slicing/slicingSelect.mli +++ b/src/plugins/slicing/slicingSelect.mli @@ -69,7 +69,7 @@ val select_pdg_nodes : SlicingTypes.sl_select val mk_select : - Db.Pdg.t -> + Pdg.Api.t -> SlicingActions.select -> (PdgTypes.Node.t * Locations.Zone.t option) list -> Locations.Zone.t option -> @@ -117,7 +117,7 @@ val select_zone_at_entry : SlicingTypes.sl_select val stmt_nodes_to_select : - Db.Pdg.t -> Cil_types.stmt -> PdgTypes.Node.t list + Pdg.Api.t -> Cil_types.stmt -> PdgTypes.Node.t list val select_stmt_computation : Kernel_function.t -> diff --git a/src/plugins/slicing/slicingState.ml b/src/plugins/slicing/slicingState.ml index b51f528fe8b..28991d80642 100644 --- a/src/plugins/slicing/slicingState.ml +++ b/src/plugins/slicing/slicingState.ml @@ -34,7 +34,7 @@ let () = (fun () -> State_dependency_graph.add_codependencies ~onto:self - [ !Db.Pdg.self; !Db.Inputs.self_external; !Db.Outputs.self_external ]) + [ Pdg.Api.self; !Db.Inputs.self_external; !Db.Outputs.self_external ]) let get () = try P.get () diff --git a/src/plugins/slicing/slicingTransform.ml b/src/plugins/slicing/slicingTransform.ml index 5d7b4d1c528..f142150160d 100644 --- a/src/plugins/slicing/slicingTransform.ml +++ b/src/plugins/slicing/slicingTransform.ml @@ -138,7 +138,7 @@ module Visibility (SliceName : sig begin SlicingParameters.debug ~level:3 "[SlicingTransform.Visibility.all_nodes_visible] node %a invisible" - (!Db.Pdg.pretty_node true) n; + (Pdg.Api.pretty_node true) n; false end else visi @@ -173,7 +173,7 @@ module Visibility (SliceName : sig SlicingParameters.debug ~level:2 "[SlicingTransform.Visibility.data_nodes_visible]@\n\ node %a invisible" - (!Db.Pdg.pretty_node true) n; + (Pdg.Api.pretty_node true) n; false end else visi @@ -242,10 +242,10 @@ module Visibility (SliceName : sig | Iproto -> false | Iff {slice = ff} -> let kf = SlicingMacros.get_ff_kf ff in - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in try let ctrl_nodes, decl_nodes, data_info = - !Db.Pdg.find_code_annot_nodes pdg stmt annot + Pdg.Api.find_code_annot_nodes pdg stmt annot in let data_visible = data_nodes_visible ff (decl_nodes, data_info) in let visible = ((all_nodes_visible ff ctrl_nodes) && data_visible) in @@ -276,9 +276,9 @@ module Visibility (SliceName : sig | Iproto -> true | Iff {slice = ff} -> let kf = SlicingMacros.get_ff_kf ff in - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in try - let nodes = !Db.Pdg.find_fun_precond_nodes pdg p in + let nodes = Pdg.Api.find_fun_precond_nodes pdg p in data_nodes_visible ff nodes with NoDataInfo -> all_logic_var_visible ff p @@ -296,9 +296,9 @@ module Visibility (SliceName : sig | Iproto -> true | Iff {slice = ff} -> let kf = SlicingMacros.get_ff_kf ff in - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in try - let nodes = !Db.Pdg.find_fun_postcond_nodes pdg p in + let nodes = Pdg.Api.find_fun_postcond_nodes pdg p in data_nodes_visible ff nodes with NoDataInfo -> all_logic_var_visible ff p @@ -316,9 +316,9 @@ module Visibility (SliceName : sig | Iproto -> true | Iff {slice = ff} -> let kf = SlicingMacros.get_ff_kf ff in - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in try - let nodes = !Db.Pdg.find_fun_variant_nodes pdg v in + let nodes = Pdg.Api.find_fun_variant_nodes pdg v in data_nodes_visible ff nodes with NoDataInfo -> all_logic_var_visible_term ff v in SlicingParameters.debug ~level:2 "[SlicingTransform.Visibility.fun_variant_visible] -> %s" diff --git a/src/plugins/sparecode/globs.ml b/src/plugins/sparecode/globs.ml index 860f24fa634..7db1fca385b 100644 --- a/src/plugins/sparecode/globs.ml +++ b/src/plugins/sparecode/globs.ml @@ -160,7 +160,7 @@ let () = (fun () -> State_dependency_graph.add_codependencies ~onto:Result.self - [ !Db.Pdg.self; !Db.Outputs.self_external ]) + [ Pdg.Api.self; !Db.Outputs.self_external ]) let rm_unused_decl = Result.memo diff --git a/src/plugins/sparecode/register.ml b/src/plugins/sparecode/register.ml index b684d758b6b..3ac3e1d4ccb 100644 --- a/src/plugins/sparecode/register.ml +++ b/src/plugins/sparecode/register.ml @@ -43,7 +43,7 @@ let () = (fun () -> State_dependency_graph.add_codependencies ~onto:Result.self - [ !Db.Pdg.self; !Db.Outputs.self_external ]) + [ Pdg.Api.self; !Db.Outputs.self_external ]) module P = Sparecode_params diff --git a/src/plugins/sparecode/spare_marks.ml b/src/plugins/sparecode/spare_marks.ml index 2f0c83674a9..314e896c662 100644 --- a/src/plugins/sparecode/spare_marks.ml +++ b/src/plugins/sparecode/spare_marks.ml @@ -25,7 +25,7 @@ let fatal fmt = Sparecode_params.fatal fmt (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) (** The project is composed of [FctIndex] marked with [BoolMark] - * to be used by [Pdg.Register.F_Proj], and another table to store if a function + * to be used by [Pdg.Api.Marks.F_Proj], and another table to store if a function * is visible (useful for Top PDG). *) (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) @@ -122,7 +122,7 @@ module Config = struct end -module ProjBoolMarks = Pdg.Register.F_Proj (Config) +module ProjBoolMarks = Pdg.Api.Marks.F_Proj (Config) type proj = ProjBoolMarks.t * unit KfTopVisi.t type fct = ProjBoolMarks.fct @@ -172,7 +172,7 @@ let rec add_pdg_selection to_select pdg sel_mark = match to_select with | [] -> let l = match sel_mark with None -> [] | Some m -> [m] in [(pdg, l)] | (p, ln) :: tl -> - if Db.Pdg.from_same_fun p pdg + if Pdg.Api.from_same_fun p pdg then let ln = match sel_mark with None -> ln | Some sel_mark -> sel_mark::ln @@ -273,7 +273,7 @@ let rec process_call_inputs proj = (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) let select_entry_point proj _kf pdg = - let ctrl = !Db.Pdg.find_entry_point_node pdg in + let ctrl = Pdg.Api.find_entry_point_node pdg in let to_select = add_node_to_select true [] None ctrl in select_pdg_elements proj pdg to_select @@ -281,9 +281,9 @@ let select_all_outputs proj kf pdg = let outputs = !Db.Outputs.get_external kf in debug 1 "@[selecting output zones %a@]" Locations.Zone.pretty outputs; try - let nodes, undef = !Db.Pdg.find_location_nodes_at_end pdg outputs in + let nodes, undef = Pdg.Api.find_location_nodes_at_end pdg outputs in let nodes = - try ((!Db.Pdg.find_ret_output_node pdg),None) :: nodes + try ((Pdg.Api.find_ret_output_node pdg),None) :: nodes with Not_found -> nodes in let nodes_and_co = ([], [], Some (nodes, undef)) in @@ -308,7 +308,7 @@ class annot_visitor ~filter pdg = object (self) let stmt = Option.get self#current_stmt in debug 1 "selecting annotation : %a @." Printer.pp_code_annotation annot; - let info = !Db.Pdg.find_code_annot_nodes pdg stmt annot in + let info = Pdg.Api.find_code_annot_nodes pdg stmt annot in to_select <- add_nodes_and_undef_to_select true info to_select with Not_found -> () (* unreachable *) @@ -322,7 +322,7 @@ end let select_annotations ~select_annot ~select_slice_pragma proj = let visit_fun kf = debug 1 "look for annotations in function %a@." Kernel_function.pretty kf; - let pdg = !Db.Pdg.get kf in + let pdg = Pdg.Api.get kf in if PdgTypes.Pdg.is_top pdg then debug 1 "pdg top: skip annotations" else if PdgTypes.Pdg.is_bottom pdg then debug 1 "pdg bottom: skip annotations" @@ -357,7 +357,7 @@ let select_useful_things ~select_annot ~select_slice_pragma kf_entry = assert (!call_in_to_check = []); debug 1 "selecting function %a outputs and entry point@." Kernel_function.pretty kf_entry; - let pdg = !Db.Pdg.get kf_entry in + let pdg = Pdg.Api.get kf_entry in if PdgTypes.Pdg.is_top pdg then KfTopVisi.set proj kf_entry else if PdgTypes.Pdg.is_bottom pdg diff --git a/src/plugins/sparecode/transform.ml b/src/plugins/sparecode/transform.ml index e2280ec81b2..b22d74c35c0 100644 --- a/src/plugins/sparecode/transform.ml +++ b/src/plugins/sparecode/transform.ml @@ -41,7 +41,7 @@ module BoolInfo = struct | Some fm -> Spare_marks.key_visible fm key in Sparecode_params.debug ~level:3 "%s : %a -> %b" - txt !Db.Pdg.pretty_key key visible; + txt Pdg.Api.pretty_key key visible; visible let param_visible (fm,_) n = diff --git a/tests/pdg/dyn_dpds.ml b/tests/pdg/dyn_dpds.ml index 716e5067f6a..4907cf29314 100644 --- a/tests/pdg/dyn_dpds.ml +++ b/tests/pdg/dyn_dpds.ml @@ -21,29 +21,29 @@ let main _ = File.pretty_ast (); Kernel.Debug.set memo_debug ; let kf = Globals.Functions.find_def_by_name "main" in - let pdg = !Db.Pdg.get kf in - Format.printf "%a@." (!Db.Pdg.pretty ~bw:false) pdg; - !Db.Pdg.extract pdg "dyn_dpds_0.dot"; + let pdg = Pdg.Api.get kf in + Format.printf "%a@." (Pdg.Api.pretty ~bw:false) pdg; + Pdg.Api.extract pdg "dyn_dpds_0.dot"; let assert_sid = 5 in (* assert ( *p>G) *) let assert_stmt, kf = Kernel_function.find_from_sid assert_sid in let _assert_node = - match !Db.Pdg.find_simple_stmt_nodes pdg assert_stmt with + match Pdg.Api.find_simple_stmt_nodes pdg assert_stmt with | n::[] -> n | _ -> assert false in let star_p = get_zones "*p" (assert_stmt, kf) in let data_nodes, undef = - !Db.Pdg.find_location_nodes_at_stmt pdg assert_stmt ~before:true star_p + Pdg.Api.find_location_nodes_at_stmt pdg assert_stmt ~before:true star_p in assert (undef = None); let g_zone = get_zones "G" (assert_stmt, kf) in let g_nodes, undef = - !Db.Pdg.find_location_nodes_at_stmt pdg assert_stmt ~before:true g_zone + Pdg.Api.find_location_nodes_at_stmt pdg assert_stmt ~before:true g_zone in let _data_nodes = g_nodes @ data_nodes in let undef = match undef with None -> assert false | Some z -> z in Format.printf "Warning : cannot select %a in this function...@\n" Locations.Zone.pretty undef; - Format.printf "%a@." (!Db.Pdg.pretty ~bw:false) pdg; - !Db.Pdg.extract pdg "dyn_dpds_1.dot" + Format.printf "%a@." (Pdg.Api.pretty ~bw:false) pdg; + Pdg.Api.extract pdg "dyn_dpds_1.dot" let () = Db.Main.extend main diff --git a/tests/pdg/sets.ml b/tests/pdg/sets.ml index f9759901253..8ebb56e106c 100644 --- a/tests/pdg/sets.ml +++ b/tests/pdg/sets.ml @@ -1,15 +1,14 @@ -open Db;; open Cil_types;; let pp_nodes msg nodes = Kernel.result "%s" msg ; - List.iter (fun n -> Kernel.result "%a" (!Pdg.pretty_node false) n) nodes;; + List.iter (fun n -> Kernel.result "%a" (Pdg.Api.pretty_node false) n) nodes;; exception Find of varinfo;; let main _ = let f = Globals.Functions.find_by_name "f" in - let pdg = !Pdg.get f in + let pdg = Pdg.Api.get f in (* Uncomment to retrieve sid *) (*Kernel.Debug.set 1;; @@ -17,8 +16,8 @@ let main _ = *) (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) let stmt_1 = fst (Kernel_function.find_from_sid 1) in (* y = 0 *) - let node = !Pdg.find_stmt_node pdg stmt_1 in - let nodes = !Pdg.all_uses pdg [node] in + let node = Pdg.Api.find_stmt_node pdg stmt_1 in + let nodes = Pdg.Api.all_uses pdg [node] in pp_nodes "Test [all_uses] stmt1" nodes; (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) @@ -32,7 +31,7 @@ let main _ = let y_zone = Locations.(enumerate_valid_bits Read (loc_of_varinfo y)) in let y_at_11_nodes, undef = (* y=5 *) - !Pdg.find_location_nodes_at_stmt + Pdg.Api.find_location_nodes_at_stmt pdg (fst (Kernel_function.find_from_sid 11)) ~before:false y_zone in @@ -41,15 +40,15 @@ let main _ = let () = pp_nodes "Test [find_location_nodes_at_stmt] y@11" y_at_11_nodes in (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) - let nodes = !Pdg.all_dpds pdg y_at_11_nodes in + let nodes = Pdg.Api.all_dpds pdg y_at_11_nodes in let () = pp_nodes "Test [all_dpds] y@11" nodes in (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) - let nodes = !Pdg.all_uses pdg y_at_11_nodes in + let nodes = Pdg.Api.all_uses pdg y_at_11_nodes in let () = pp_nodes "Test [all_uses] y@11" nodes in (*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*) let all_related_nodes pdg = - let all n = (!Pdg.direct_uses pdg n) @ (!Pdg.direct_dpds pdg n) in - !Pdg.custom_related_nodes all + let all n = (Pdg.Api.direct_uses pdg n) @ (Pdg.Api.direct_dpds pdg n) in + Pdg.Api.custom_related_nodes all in let nodes = all_related_nodes pdg y_at_11_nodes in pp_nodes "Test [all_related_nodes] y@11" nodes diff --git a/tests/slicing/libSelect.ml b/tests/slicing/libSelect.ml index fae01cc8b50..8fed3fdca1f 100644 --- a/tests/slicing/libSelect.ml +++ b/tests/slicing/libSelect.ml @@ -29,7 +29,7 @@ let print_stmt kf = Slicing.PrintSlice.print_fct_stmts fmt kf (* print PDG (for debugging purposes) *) -let print_pdg kf = !Db.Pdg.pretty fmt (!Db.Pdg.get kf) ;; +let print_pdg kf = Pdg.Api.pretty fmt (Pdg.Api.get kf) ;; let print_ff ff = Slicing.Api.Slice.pretty fmt ff diff --git a/tests/slicing/min_call.ml b/tests/slicing/min_call.ml index ebb0e3e8983..80fbe7ad125 100644 --- a/tests/slicing/min_call.ml +++ b/tests/slicing/min_call.ml @@ -31,8 +31,8 @@ let main _ = * the call to [send_bis] is visible as wished. *) Slicing.Api.Project.reset_slicing (); - (*let pdg_k = !Db.Pdg.get kf_k;;*) - let calls = !Db.Pdg.find_call_stmts ~caller:kf_k(*pdg_k*) kf_send_bis in + (*let pdg_k = Pdg.Api.get kf_k;;*) + let calls = Pdg.Api.find_call_stmts ~caller:kf_k(*pdg_k*) kf_send_bis in let sb_call = match calls with c::[] -> c | _ -> assert false in let mark = Slicing.Api.Mark.make ~data:true ~addr:false ~ctrl:false in let select = Slicing.Api.Select.select_stmt_internal kf_k sb_call mark in @@ -52,8 +52,8 @@ let main _ = * But as [send_bis] is an undefined function, this makes no difference. *) Slicing.Api.Project.reset_slicing (); - (*let pdg_k = !Db.Pdg.get kf_k;;*) - let calls = !Db.Pdg.find_call_stmts (*pdg_k*)~caller:kf_k kf_send_bis in + (*let pdg_k = Pdg.Api.get kf_k;;*) + let calls = Pdg.Api.find_call_stmts (*pdg_k*)~caller:kf_k kf_send_bis in let sb_call = match calls with c::[] -> c | _ -> assert false in let mark = Slicing.Api.Mark.make ~data:true ~addr:false ~ctrl:false in let select = Slicing.Api.Select.select_min_call_internal kf_k sb_call mark in diff --git a/tests/slicing/select_by_annot.ml b/tests/slicing/select_by_annot.ml index c3dec000e62..39e3e6d67a0 100644 --- a/tests/slicing/select_by_annot.ml +++ b/tests/slicing/select_by_annot.ml @@ -7,7 +7,7 @@ open LibSelect;; let main _ = Slicing.Api.Project.reset_slicing (); - let pretty_pdg fmt kf = !Db.Pdg.pretty fmt (!Db.Pdg.get kf) in + let pretty_pdg fmt kf = Pdg.Api.pretty fmt (Pdg.Api.get kf) in let add_annot kf = let mark = Slicing.Api.Mark.make ~data:true ~addr:false ~ctrl:false in let select = Slicing.Api.Select.empty_selects in diff --git a/tests/slicing/simple_intra_slice.ml b/tests/slicing/simple_intra_slice.ml index f9e17c3b87c..7a7e189a1c9 100644 --- a/tests/slicing/simple_intra_slice.ml +++ b/tests/slicing/simple_intra_slice.ml @@ -7,7 +7,7 @@ include LibSelect;; let main _ = Slicing.Api.Project.reset_slicing (); - let pretty_pdg fmt kf = !Db.Pdg.pretty fmt (!Db.Pdg.get kf) in + let pretty_pdg fmt kf = Pdg.Api.pretty fmt (Pdg.Api.get kf) in let apply_all_actions = Slicing.Api.Request.apply_all_internal in let print_slice = Slicing.Api.Slice.pretty in let print_fct_stmts kf = -- GitLab