diff --git a/src/plugins/impact/pdg_aux.ml b/src/plugins/impact/pdg_aux.ml index a486d6adbac42a5d101fc50b2341caddd9689fbb..290979130415c3c1cb9b92426d5017c95b0c8862 100644 --- a/src/plugins/impact/pdg_aux.ml +++ b/src/plugins/impact/pdg_aux.ml @@ -166,9 +166,7 @@ let find_call_input_nodes pdg_caller call_stmt ?(z=Locations.Zone.top) in_key = let all_call_input_nodes ~caller:pdg_caller ~callee:(kf_callee, pdg_callee) call_stmt = let real_inputs = - let inout = - Inout.Operational_inputs.get_internal_precise ~stmt:call_stmt kf_callee - in + let inout = Inout.get_precise_inout ~stmt:call_stmt kf_callee in inout.Inout_type.over_inputs_if_termination in let test_in acc (in_key, in_node) = diff --git a/src/plugins/inout/Inout.ml b/src/plugins/inout/Inout.ml new file mode 100644 index 0000000000000000000000000000000000000000..9eb53af878a48b71db0473a78803356da097be97 --- /dev/null +++ b/src/plugins/inout/Inout.ml @@ -0,0 +1,36 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2023 *) +(* 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). *) +(* *) +(**************************************************************************) + +let expr_inputs = Inputs.expr +let stmt_inputs = Inputs.statement +let kf_inputs = Inputs.get_internal +let kf_external_inputs = Inputs.get_external + +let stmt_outputs = Outputs.statement +let kf_outputs = Outputs.get_internal +let kf_external_outputs = Outputs.get_external + +let get_precise_inout = Operational_inputs.get_internal_precise + +let states = [ Inputs.self; Outputs.self ] +let proxy = State_builder.Proxy.(create "inout" Both states) +let self = State_builder.Proxy.get proxy diff --git a/src/plugins/inout/Inout.mli b/src/plugins/inout/Inout.mli new file mode 100644 index 0000000000000000000000000000000000000000..90a3cb7230ef0a3ef10a40f338f17e4789d2eadd --- /dev/null +++ b/src/plugins/inout/Inout.mli @@ -0,0 +1,56 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2023 *) +(* 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). *) +(* *) +(**************************************************************************) + +open Cil_types + +(** Returns the memory zone needed to evaluate the given expression at the + given statement. *) +val expr_inputs: stmt -> exp -> Locations.Zone.t + +(** Returns the memory zone read by the given statement. *) +val stmt_inputs: stmt -> Locations.Zone.t + +(** Returns the memory zone modified by the given statement. *) +val stmt_outputs: stmt -> Locations.Zone.t + +(** Returns the memory zone read by the given function, including its + local and formal variables. *) +val kf_inputs: kernel_function -> Locations.Zone.t + +(** Returns the memory zone read by the given function, without its + local and formal variables. *) +val kf_external_inputs: kernel_function -> Locations.Zone.t + +(** Returns the memory zone modified by the given function, including its + local and formal variables. *) +val kf_outputs: kernel_function -> Locations.Zone.t + +(** Returns the memory zone modified by the given function, without its + local and formal variables. *) +val kf_external_outputs: kernel_function -> Locations.Zone.t + +(** Returns the inputs/outputs computed for the given function. + If [stmt] is specified and is a possible call to the given function, + returns the inputs/outputs for this call specifically. *) +val get_precise_inout: ?stmt:stmt -> kernel_function -> Inout_type.t + +val self: State.t diff --git a/src/plugins/inout/outputs.mli b/src/plugins/inout/outputs.mli index 006d55cae5cef6654afe40115ab8fda08419ff86..192edda7fa5ee3c80f93d96fdf0afe495204402b 100644 --- a/src/plugins/inout/outputs.mli +++ b/src/plugins/inout/outputs.mli @@ -23,6 +23,7 @@ val self: State.t val compute: Cil_types.kernel_function -> unit +val get_internal: Cil_types.kernel_function -> Locations.Zone.t val get_external: Cil_types.kernel_function -> Locations.Zone.t val statement: Cil_types.stmt -> Locations.Zone.t diff --git a/src/plugins/reduc/collect.ml b/src/plugins/reduc/collect.ml index d19635aa3cd8a9245687dc777d1064fe9a88e6b9..d2192b5df7a315447423a7d94d1c17d608232d0e 100644 --- a/src/plugins/reduc/collect.ml +++ b/src/plugins/reduc/collect.ml @@ -122,7 +122,7 @@ class inout_vis with Kernel_function.No_Statement -> assert false method !vstmt stmt = - let out = Inout.Outputs.statement stmt in + let out = Inout.stmt_outputs stmt in let filter_out vi = let open Locations in let zone = enumerate_bits (loc_of_varinfo vi) in diff --git a/src/plugins/scope/datascope.ml b/src/plugins/scope/datascope.ml index 23c2421b339068bbcd61c7f2c139a106a79477e2..29708325fc01fe1491e081b383a2fbad776e0b9a 100644 --- a/src/plugins/scope/datascope.ml +++ b/src/plugins/scope/datascope.ml @@ -87,7 +87,7 @@ let get_writes stmt lval = let register_modified_zones lmap stmt = let register lmap zone = InitSid.add_zone lmap zone stmt in let aux_out out kf = - let inout= Inout.Operational_inputs.get_internal_precise ~stmt kf in + let inout= Inout.get_precise_inout ~stmt kf in Locations.Zone.join out inout.Inout_type.over_outputs in match stmt.skind with diff --git a/src/plugins/slicing/fct_slice.ml b/src/plugins/slicing/fct_slice.ml index 6d09aef97e71bd9f684dff384cad6c92e0760a36..3818ca7685f0adc7a2601a704c4a7b0b55e51904 100644 --- a/src/plugins/slicing/fct_slice.ml +++ b/src/plugins/slicing/fct_slice.ml @@ -424,7 +424,7 @@ end = struct let add_mark = let kf = fi_to_call.SlicingInternals.fi_kf in let op_inputs = - Inout.Operational_inputs.get_internal_precise ~stmt:call kf in + Inout.get_precise_inout ~stmt:call kf in let z = op_inputs.Inout_type.over_inputs in match s with | PdgMarks.SelNode (_, None) -> true @@ -1308,7 +1308,7 @@ let apply_change_call ff call f_to_call = try let kf = ff_to_call.SlicingInternals.ff_fct.SlicingInternals.fi_kf in let op_inputs = - Inout.Operational_inputs.get_internal_precise ~stmt:call kf in + Inout.get_precise_inout ~stmt:call kf in let z = op_inputs.Inout_type.over_inputs in (*Format.printf "##Call at %a,@ kf %a,@ @[Z %a@]@." Cil.d_loc (Cil_datatype.Stmt.loc call) diff --git a/src/plugins/slicing/slicingCmds.ml b/src/plugins/slicing/slicingCmds.ml index 637319e1b3db053e3286a93110e3e7fbf7ff7b2a..b5b773dad33e63574c1ff48cc081abcde0767ecf 100644 --- a/src/plugins/slicing/slicingCmds.ml +++ b/src/plugins/slicing/slicingCmds.ml @@ -247,7 +247,7 @@ let select_func_calls_to set ~spare kf = SlicingMarks.mk_user_mark ~data:nspare ~addr:nspare ~ctrl:nspare in assert (Eva.Analysis.is_computed ()); - let outputs = Inout.Outputs.get_external kf in + let outputs = Inout.kf_external_outputs kf in select_entry_point_and_some_inputs_outputs set ~mark kf ~return:true ~outputs @@ -407,8 +407,8 @@ let select_lval_rw set mark ~rd ~wr ~eval kf ki_opt= in assert (Eva.Results.is_called kf) ; (* otherwise [!Db.Outputs.get_external kf] gives weird results *) - select_inter_zone select_wr zone_wr_opt (Inout.Outputs.get_external kf) ; - select_inter_zone select_rd zone_rd_opt (Inout.Inputs.get_external kf) + select_inter_zone select_wr zone_wr_opt (Inout.kf_external_outputs kf) ; + select_inter_zone select_rd zone_rd_opt (Inout.kf_external_inputs kf) end )); !ac diff --git a/src/plugins/slicing/slicingState.ml b/src/plugins/slicing/slicingState.ml index bd8abdff6869f58d99864aa2080523371fb6ba2c..a95aa8e3435f45d3d682eeea2285bcd151b55241 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 - [ Pdg.Api.self; Inout.Inputs.self ; Inout.Outputs.self ]) + [ Pdg.Api.self; Inout.self ]) let get () = try P.get () diff --git a/src/plugins/sparecode/globs.ml b/src/plugins/sparecode/globs.ml index dafe82987f4666ef9e8829016410f867de06f21c..a55dbb45410a574f2162e3be54943a54ad8cddf3 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 - [ Pdg.Api.self; Inout.Outputs.self ]) + [ Pdg.Api.self; Inout.self ]) let rm_unused_decl = Result.memo diff --git a/src/plugins/sparecode/register.ml b/src/plugins/sparecode/register.ml index 8e2d7af9f7e6727d1bff2bf9bdb99a2dd676847e..b413b26e45126b3d60f2e70442d5a8a019e99351 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 - [ Pdg.Api.self; Inout.Outputs.self ]) + [ Pdg.Api.self; Inout.self ]) module P = Sparecode_params diff --git a/src/plugins/sparecode/spare_marks.ml b/src/plugins/sparecode/spare_marks.ml index 48d1f2884d9b2896a01efe29993f55a05e9eb48f..271a330669b6f55678c44c16a5fbb629fb8e6a45 100644 --- a/src/plugins/sparecode/spare_marks.ml +++ b/src/plugins/sparecode/spare_marks.ml @@ -280,7 +280,7 @@ let select_entry_point proj _kf pdg = select_pdg_elements proj pdg to_select let select_all_outputs proj kf pdg = - let outputs = Inout.Outputs.get_external kf in + let outputs = Inout.kf_external_outputs kf in debug 1 "@[selecting output zones %a@]" Locations.Zone.pretty outputs; try let nodes, undef = Pdg.Api.find_location_nodes_at_end pdg outputs in diff --git a/src/plugins/studia/reads.ml b/src/plugins/studia/reads.ml index 457a6a17da99f7fc84dc79d0d45ade880205669e..058691cd35cfaba5343dd7bbbd8ada79029b0270 100644 --- a/src/plugins/studia/reads.ml +++ b/src/plugins/studia/reads.ml @@ -37,11 +37,11 @@ class find_read zlval = object method! vstmt_aux stmt = let aux_call lvopt _kf args _loc = - let z = Inout.Inputs.statement stmt in + let z = Inout.stmt_inputs stmt in if Zone.intersects z zlval then begin (* Computes what is read to evaluate [args] and [lvopt] *) let deps = - List.map (Inout.Inputs.expr stmt) args + List.map (Inout.expr_inputs stmt) args in let deps = List.fold_left Zone.join Zone.bottom deps in let deps = match lvopt with @@ -54,7 +54,7 @@ class find_read zlval = object (* now determine if the functions called at [stmt] read directly or indirectly [zlval] *) let aux_kf (direct, indirect) kf = - let inputs = Inout.Inputs.get_internal kf in + let inputs = Inout.kf_inputs kf in (* TODO: change to this once we can get "full" inputs through Inout. Currently, non operational inputs disappear, and this function is not suitable. @@ -85,13 +85,13 @@ class find_read zlval = object Cil.treat_constructor_as_func aux_call v f args k l; Cil.SkipChildren | Instr _ -> - let z = Inout.Inputs.statement stmt in + let z = Inout.stmt_inputs stmt in if Zone.intersects z zlval then begin res <- Direct stmt :: res end; Cil.SkipChildren | If (e, _, _, _) | Switch (e, _, _, _) | Return (Some e, _) -> - let z = Inout.Inputs.expr stmt e in + let z = Inout.expr_inputs stmt e in if Zone.intersects z zlval then begin res <- Direct stmt :: res end; @@ -104,7 +104,7 @@ end let compute z = let vis = new find_read z in let aux_kf_fundec kf = - let all_in = Inout.Inputs.get_internal kf in + let all_in = Inout.kf_inputs kf in if Zone.intersects all_in z then begin let fundec = Kernel_function.get_definition kf in ignore diff --git a/src/plugins/studia/writes.ml b/src/plugins/studia/writes.ml index 65a670198c4f290a7c78230672a3030deafd52de..4d566dfcc6430db48ec456b18d8cf68b4238070b 100644 --- a/src/plugins/studia/writes.ml +++ b/src/plugins/studia/writes.ml @@ -65,7 +65,7 @@ let compare w1 w2 = (** Does the functions called at [stmt] modify directly or indirectly [zlval] *) let effects_of_call stmt zlval effects = let aux_kf (direct, indirect) kf = - let inout = Inout.Operational_inputs.get_internal_precise ~stmt kf in + let inout = Inout.get_precise_inout ~stmt kf in let out = inout.Inout_type.over_outputs in if Zone.intersects out zlval then if Eva.Analysis.use_spec_instead_of_definition kf then @@ -89,7 +89,7 @@ class find_write_insts zlval = object (self) let aux_call lvopt _kf _args _loc = (* Direct effect through the writing of [lvopt], or indirect inside the call. *) - let z = Inout.Outputs.statement stmt in + let z = Inout.stmt_outputs stmt in if Zone.intersects z zlval then let direct = match lvopt with | None -> false @@ -106,7 +106,7 @@ class find_write_insts zlval = object (self) match i with | Set _ | Local_init(_, AssignInit _, _) -> (* Effect only throuh the written l-value *) - let z = Inout.Outputs.statement stmt in + let z = Inout.stmt_outputs stmt in if Zone.intersects z zlval then begin res <- Assign stmt :: res end @@ -123,7 +123,7 @@ end let inst_writes z = let vis = new find_write_insts z in let aux_kf_fundec kf = - let all_out = Inout.Operational_inputs.get_internal_precise kf in + let all_out = Inout.get_precise_inout kf in let zout = all_out.Inout_type.over_outputs in if Zone.intersects zout z then begin let fundec = Kernel_function.get_definition kf in diff --git a/tests/slicing/simple_intra_slice.ml b/tests/slicing/simple_intra_slice.ml index a5df5c95d1f7fd6d0e63cfad5922857b62fc0e50..e60a1638a7c80ed04c83d6de012bcb1146ace84e 100644 --- a/tests/slicing/simple_intra_slice.ml +++ b/tests/slicing/simple_intra_slice.ml @@ -47,7 +47,7 @@ let main _ = in let print_outputs fct_name = let fct = Globals.Functions.find_by_name fct_name in - let outs = Inout.Outputs.get_external fct in + let outs = Inout.kf_external_outputs fct in Format.printf "Sorties de la fonction %s = %a\n" fct_name Locations.Zone.pretty outs in