From 2ff2492ac382cdbab2e684f073836c2be7a66eb0 Mon Sep 17 00:00:00 2001
From: Valentin Perrelle <valentin.perrelle@cea.fr>
Date: Mon, 7 Feb 2022 16:58:31 +0100
Subject: [PATCH] [Slicing] Use the new Eva API

---
 src/plugins/slicing/api.ml              |  5 ++-
 src/plugins/slicing/fct_slice.ml        | 19 +++-------
 src/plugins/slicing/printSlice.ml       |  4 +--
 src/plugins/slicing/register.ml         |  2 +-
 src/plugins/slicing/register_gui.ml     | 18 +++++-----
 src/plugins/slicing/slicingCmds.ml      | 46 ++++++++++++-------------
 src/plugins/slicing/slicingMacros.ml    |  9 ++---
 src/plugins/slicing/slicingProject.ml   |  4 +--
 src/plugins/slicing/slicingSelect.ml    |  4 +--
 src/plugins/slicing/slicingState.ml     |  2 +-
 src/plugins/slicing/slicingTransform.ml |  2 +-
 11 files changed, 51 insertions(+), 64 deletions(-)

diff --git a/src/plugins/slicing/api.ml b/src/plugins/slicing/api.ml
index 3ece47ef723..13b39597d7d 100644
--- a/src/plugins/slicing/api.ml
+++ b/src/plugins/slicing/api.ml
@@ -413,10 +413,9 @@ module Slice = struct
 
   let get_called_funcs ff stmt =
     match stmt.skind with
-    | Instr (Call (_,expr_f,_,_)) ->
+    | Instr (Call _) ->
       if snd (Fct_slice.get_called_slice ff stmt) then
-        Kernel_function.Hptset.elements
-          (snd (!Db.Value.expr_to_kernel_function (Kstmt stmt) ~deps:None expr_f))
+        Eva.Results.callee stmt
       else
         []
     | Instr (Local_init (_, ConsInit (f, _, _), _)) -> [ Globals.Functions.get f ]
diff --git a/src/plugins/slicing/fct_slice.ml b/src/plugins/slicing/fct_slice.ml
index 47d922e5bb0..8668de2d327 100644
--- a/src/plugins/slicing/fct_slice.ml
+++ b/src/plugins/slicing/fct_slice.ml
@@ -55,8 +55,8 @@ let exists_fun_callers fpred kf =
     else begin
       table := Kernel_function.Set.add kf !table ;
       List.exists
-        (fun (kf,_) -> exists_fun_callers kf)
-        (!Db.Value.callers kf)
+        (fun kf -> exists_fun_callers kf)
+        (Eva.Results.callers kf)
     end
   in
   exists_fun_callers kf
@@ -146,16 +146,7 @@ end = struct
 
   let indirectly_called_src_functions call_id =
     let _, stmt = call_id in
-    let funcexp = match stmt.skind with
-      | Instr (Call (_,funcexp,_,_)) -> funcexp
-      | Instr (Local_init (_, ConsInit (f, _, _), _)) -> Cil.evar f
-      | _ -> assert false
-    in
-    let _, called_functions =
-      !Db.Value.expr_to_kernel_function
-        (Kstmt stmt) ~deps:(Some Locations.Zone.bottom) funcexp
-    in
-    Kernel_function.Hptset.elements called_functions
+    Eva.Results.callee stmt
 
   (** [call_id] is a call to [g] in [f].
    * we don't want [f] to call [g] anymore, so we have to update [g] [called_by]
@@ -1463,12 +1454,12 @@ let merge_fun_callers get_list get_value merge is_top acc kf =
           raise StopMerging (* acceleration when top is reached *)
       in
       let rec merge_fun_callers kf =
-        let merge_fun_caller (kf,_) = merge_fun_callers kf in
+        let merge_fun_caller kf = merge_fun_callers kf in
         let vf = Kernel_function.get_vi kf in
         if not (Cil_datatype.Varinfo.Set.mem vf !table) then begin
           table := Cil_datatype.Varinfo.Set.add vf !table ;
           List.iter (fun x -> merge (get_value x)) (get_list kf) ;
-          List.iter merge_fun_caller (!Db.Value.callers kf)
+          List.iter merge_fun_caller (Eva.Results.callers kf)
         end
         (*  else no way to add something, the [kf] contribution is already
             accumulated. *)
diff --git a/src/plugins/slicing/printSlice.ml b/src/plugins/slicing/printSlice.ml
index 63986e183eb..9c5bd9baed6 100644
--- a/src/plugins/slicing/printSlice.ml
+++ b/src/plugins/slicing/printSlice.ml
@@ -204,10 +204,10 @@ module PrintProject = struct
   let iter_edges_src_fun f =
     let do_kf_calls kf =
       let fi = SlicingMacros.get_kf_fi kf in
-      let doit (kf_caller,_) =
+      let doit kf_caller =
         let fi_caller = SlicingMacros.get_kf_fi kf_caller in
         f ((Src fi_caller, Src fi), None)
-      in List.iter doit (!Db.Value.callers kf)
+      in List.iter doit (Eva.Results.callers kf)
     in
     Globals.Functions.iter do_kf_calls
 
diff --git a/src/plugins/slicing/register.ml b/src/plugins/slicing/register.ml
index 3f32606a217..4166762d3cc 100644
--- a/src/plugins/slicing/register.ml
+++ b/src/plugins/slicing/register.ml
@@ -27,7 +27,7 @@ let main () =
     (* have to do the value analysis before the selections
      * because some functions use its results,
      * and the value analysis is not launched automatically. *)
-    !Db.Value.compute ();
+    Eva.Analysis.compute ();
 
     let project_name = SlicingParameters.ProjectName.get () in
     Api.Project.reset_slicing ();
diff --git a/src/plugins/slicing/register_gui.ml b/src/plugins/slicing/register_gui.ml
index 0650a8a5d7d..92251b205bb 100644
--- a/src/plugins/slicing/register_gui.ml
+++ b/src/plugins/slicing/register_gui.ml
@@ -92,7 +92,7 @@ let msg_help_libraries =
    undefined functions."
 
 let check_value_computed (main_ui:Design.main_window_extension_points) =
-  if Db.Value.is_computed () then true
+  if Eva.Analysis.is_computed () then true
   else
     let answer = GToolbox.question_box
         ~title:("Eva Needed")
@@ -102,7 +102,7 @@ let check_value_computed (main_ui:Design.main_window_extension_points) =
          ^"Do you want to run Eva with its current settings now?")
     in
     if answer = 1 then
-      match main_ui#full_protect ~cancelable:true !Db.Value.compute with
+      match main_ui#full_protect ~cancelable:true Eva.Analysis.compute with
       | Some _ ->
         main_ui#redisplay (); (* New alarms *)
         true
@@ -116,7 +116,7 @@ let gui_apply_action (main_ui:Design.main_window_extension_points) f x ~info =
 
 let slicing_selector (popup_factory:GMenu.menu GMenu.factory)
     (main_ui:Design.main_window_extension_points) ~button localizable =
-  if (not (Db.Value.is_computed ()))
+  if (not (Eva.Analysis.is_computed ()))
   then
     ignore
       (popup_factory#add_item "Enable _slicing"
@@ -126,7 +126,7 @@ let slicing_selector (popup_factory:GMenu.menu GMenu.factory)
                 Enabled.set true;
                 !update_column `Visibility
               in
-              if (not (Db.Value.is_computed ())) then begin
+              if (not (Eva.Analysis.is_computed ())) then begin
                 if check_value_computed main_ui then enable ()
               end
               else enable ()
@@ -344,7 +344,7 @@ let slicing_selector (popup_factory:GMenu.menu GMenu.factory)
     in
     let some_kf_from_vi vi =
       try let kf = Globals.Functions.get vi in
-        if !Db.Value.is_called kf then Some kf else None
+        if Eva.Results.is_called kf then Some kf else None
       with Not_found -> None in
     let some_kf_from_lv  lv =
       match lv with
@@ -352,7 +352,7 @@ let slicing_selector (popup_factory:GMenu.menu GMenu.factory)
       | _ -> None
     in
     let some_kf_ki_lv kf stmt lvopt =
-      if !Db.Value.is_called kf && Db.Value.is_reachable_stmt stmt
+      if Eva.Results.is_called kf && Eva.Results.is_reachable stmt
       then Some (kf, stmt, lvopt) else None
     in
     begin  (* add menu for slicing and scope plug-in *)
@@ -386,7 +386,7 @@ let slicing_highlighter(buffer:Design.reactive_buffer) localizable ~start ~stop=
     let highlight () =
       let buffer = buffer#buffer in
       let ki = Pretty_source.ki_of_localizable localizable in
-      if Db.Value.is_accessible ki then
+      if Eva.Results.is_reachable_kinstr ki then
         let unused_code_area =
           Gtk_helper.make_tag buffer
             ~name:"slicing_unused" [`STRIKETHROUGH true ]
@@ -443,7 +443,7 @@ let slicing_highlighter(buffer:Design.reactive_buffer) localizable ~start ~stop=
           end
         in
         let tag_stmt kf stmt pb pe =
-          assert (Db.Value.is_reachable_stmt stmt) ;
+          assert (Eva.Results.is_reachable stmt) ;
           apply_on_one_project_and_merge_slices
             kf
             pb
@@ -554,7 +554,7 @@ let slicing_panel (main_ui:Design.main_window_extension_points) =
       (gui_set_slicing_level main_ui)
   in
   let refresh () =
-    let value_is_computed = Db.Value.is_computed () in
+    let value_is_computed = Eva.Analysis.is_computed () in
     let enabled = Enabled.get () in
     enabled_button#misc#set_sensitive value_is_computed ;
     slice_undef_button#misc#set_sensitive enabled ;
diff --git a/src/plugins/slicing/slicingCmds.ml b/src/plugins/slicing/slicingCmds.ml
index 79b59cc0fd5..dfd6377fa2e 100644
--- a/src/plugins/slicing/slicingCmds.ml
+++ b/src/plugins/slicing/slicingCmds.ml
@@ -71,17 +71,18 @@ struct
     * i.e. directly means when [ki] is a call,
       it doesn't don't look at the assigns clause of the called function. *)
   let get_rw_zone stmt = (* returns [Zone.t read],[Zone.t written] *)
-    assert (Db.Value.is_computed ());
+    assert (Eva.Analysis.is_computed ());
     let lval_process read_zone stmt lv =
       (* returns [read_zone] joined to [Zone.t read] by [lv], [Zone.t written] by [lv] *)
       (* The modified locations are [looking_for], those address are
          function of [deps]. *)
-      let state = Db.Value.get_stmt_state stmt in
-      let deps, zloc, _exact =
-        !Db.Value.lval_to_zone_with_deps_state
-          state ~deps:(Some read_zone) ~for_writing:true lv
+      let zloc, deps =
+        Eva.Results.(
+          before stmt |> eval_address lv |> as_zone ~access:Locations.Write |>
+          default Locations.Zone.bottom,
+          before stmt |> address_deps lv)
       in
-      deps, zloc
+      Locations.Zone.join read_zone deps, zloc
     in
     let call_process lv f args _loc =
       (* returns  [Zone.t read] by [lv, f, args], [Zone.t written] by [lv] *)
@@ -184,8 +185,8 @@ let select_entry_point_and_some_inputs_outputs set ~mark kf ~return ~outputs ~in
       add_to_selection set selection
   in if ((Locations.Zone.equal Locations.Zone.bottom outputs) && not return) ||
         (try
-           let ki = Kernel_function.find_return kf
-           in if Db.Value.is_reachable_stmt ki then
+           let stmt = Kernel_function.find_return kf
+           in if Eva.Results.is_reachable stmt then
              false
            else
              begin
@@ -210,8 +211,8 @@ let select_entry_point_and_some_inputs_outputs set ~mark kf ~return ~outputs ~in
 (* apply [select ~spare] on each callsite of [kf] and add the returned selection
    to [set]. *)
 let generic_select_func_calls select_stmt set ~spare kf =
-  assert (Db.Value.is_computed ());
-  let callers = !Db.Value.callers kf in
+  assert (Eva.Analysis.is_computed ());
+  let callers = Eva.Results.callsites kf in
   let select_calls acc (caller, stmts) =
     List.fold_left (fun acc s -> select_stmt acc ~spare s caller) acc stmts
   in
@@ -245,7 +246,7 @@ let select_func_calls_to set ~spare kf =
         let nspare = not spare in
         SlicingMarks.mk_user_mark ~data:nspare ~addr:nspare ~ctrl:nspare
       in
-      assert (Db.Value.is_computed ());
+      assert (Eva.Analysis.is_computed ());
       let outputs = !Db.Outputs.get_external kf in
       select_entry_point_and_some_inputs_outputs set ~mark kf
         ~return:true
@@ -308,7 +309,7 @@ let select_stmt_zone set mark zone ~before ki kf =
     or after (c.f. boolean [~before]) the statement [ki].
     Note: add also a transparent selection on the whole statement. *)
 let select_stmt_lval set mark lval_str ~before ki ~eval kf =
-  assert (Db.Value.is_computed ());
+  assert (Eva.Analysis.is_computed ());
   if Datatype.String.Set.is_empty lval_str
   then set
   else
@@ -319,10 +320,9 @@ let select_stmt_lval set mark lval_str ~before ki ~eval kf =
            let lval =
              !Db.Properties.Interp.term_lval_to_lval ~result:None lval_term
            in
-           let state = Db.Value.get_stmt_state eval in
-           let _deps, zone, _exact =
-             !Db.Value.lval_to_zone_with_deps_state
-               ~deps:None ~for_writing:false state lval
+           let zone =
+             Eva.Results.(before eval |> eval_address lval |> as_zone) |>
+             Result.value ~default:Locations.Zone.bottom
            in
            Locations.Zone.join zone acc)
         lval_str
@@ -342,7 +342,7 @@ let select_stmt_lval set mark lval_str ~before ki ~eval kf =
       i.e. when [ki_opt] is a call, the selection doesn't look at the assigns clause
       of a call. *)
 let select_lval_rw set mark ~rd ~wr ~eval kf ki_opt=
-  assert (Db.Value.is_computed ());
+  assert (Eva.Analysis.is_computed ());
   let zone_option ~for_writing lval_str =
     if Datatype.String.Set.is_empty lval_str
     then None
@@ -352,10 +352,10 @@ let select_lval_rw set mark ~rd ~wr ~eval kf ki_opt=
           (fun lval_str acc ->
              let lval_term = !Db.Properties.Interp.term_lval kf lval_str in
              let lval = !Db.Properties.Interp.term_lval_to_lval ~result:None lval_term in
-             let state = Db.Value.get_stmt_state eval in
-             let _deps, zone, _exact =
-               !Db.Value.lval_to_zone_with_deps_state
-                 state ~for_writing ~deps:None lval
+             let access = if for_writing then Locations.Write else Locations.Read in
+             let zone =
+               Eva.Results.(before eval |> eval_address lval |> as_zone ~access) |>
+               Result.value ~default:Locations.Zone.bottom
              in
              Locations.Zone.join zone acc)
           lval_str Locations.Zone.bottom
@@ -389,7 +389,7 @@ let select_lval_rw set mark ~rd ~wr ~eval kf ki_opt=
         | None ->
           Globals.Functions.iter
             (fun kf ->
-               if !Db.Value.is_called kf then
+               if Eva.Results.is_called kf then
                  if not (!Db.Value.use_spec_instead_of_definition kf)
                  then (* Called function with source code: just looks at its stmt *)
                    Kinstr.iter_from_func (select_rw_from_stmt kf) kf
@@ -413,7 +413,7 @@ let select_lval_rw set mark ~rd ~wr ~eval kf ki_opt=
                          ~return:false ~inputs ~outputs:Locations.Zone.bottom
 
                    in
-                   assert (!Db.Value.is_called kf) ; (* otherwise [!Db.Outputs.get_external kf] gives weird results *)
+                   assert (Eva.Results.is_called kf) ; (* otherwise [!Db.Outputs.get_external kf] gives weird results *)
                    select_inter_zone select_wr zone_wr_opt (!Db.Outputs.get_external kf) ;
                    select_inter_zone select_rd zone_rd_opt (!Db.Inputs.get_external kf)
                  end
diff --git a/src/plugins/slicing/slicingMacros.ml b/src/plugins/slicing/slicingMacros.ml
index d49a3f596c1..ebb985bc198 100644
--- a/src/plugins/slicing/slicingMacros.ml
+++ b/src/plugins/slicing/slicingMacros.ml
@@ -173,12 +173,9 @@ let is_call_stmt stmt =
   | Instr (Call _ | Local_init(_, ConsInit _,_)) -> true | _ -> false
 
 let get_called_kf call_stmt = match call_stmt.skind with
-  | Instr (Call (_, funcexp,_,_)) ->
-    let _funcexp_dpds, called_functions =
-      !Db.Value.expr_to_kernel_function ~deps:None (Kstmt call_stmt) funcexp
-    in
-    (match Kernel_function.Hptset.contains_single_elt called_functions with
-     | Some kf -> kf
+  | Instr (Call _) ->
+    (match Eva.Results.callee call_stmt with
+     | [kf] -> kf
      | _ -> raise SlicingTypes.PtrCallExpr)
   | Instr (Local_init(_, ConsInit (f, _, _), _)) -> Globals.Functions.get f
   | _ -> invalid_arg "Not a call statement !"
diff --git a/src/plugins/slicing/slicingProject.ml b/src/plugins/slicing/slicingProject.ml
index 73532548cc6..010cbdd86d4 100644
--- a/src/plugins/slicing/slicingProject.ml
+++ b/src/plugins/slicing/slicingProject.ml
@@ -222,13 +222,13 @@ let apply_appli_crit appli_crit =
   match appli_crit with
   | T.CaCall fi_to_call ->
     let kf_to_call = M.get_fi_kf fi_to_call in
-    let add_actions actions (kf_caller,_) =
+    let add_actions actions kf_caller =
       let fi_caller = M.get_kf_fi kf_caller in
       let mark = SlicingMarks.mk_user_spare in
       let action =
         SlicingActions.mk_crit_mark_calls fi_caller kf_to_call mark in
       action :: actions
-    in List.fold_left add_actions [] (!Db.Value.callers kf_to_call)
+    in List.fold_left add_actions [] (Eva.Results.callers kf_to_call)
   | _ ->
     SlicingParameters.not_yet_implemented
       "This slicing criterion on application"
diff --git a/src/plugins/slicing/slicingSelect.ml b/src/plugins/slicing/slicingSelect.ml
index 5775c6ecbe4..b4b331aabe2 100644
--- a/src/plugins/slicing/slicingSelect.ml
+++ b/src/plugins/slicing/slicingSelect.ml
@@ -105,7 +105,7 @@ let select_stmt_zone kf ?(select=empty_db_select kf) stmt ~before loc mark =
     Locations.Zone.pretty loc
     (if before then "before" else "after") stmt.sid
     SlicingMarks.pretty_mark mark;
-  if not (Db.Value.is_reachable_stmt stmt) then
+  if not (Eva.Results.is_reachable stmt) then
     begin
       SlicingParameters.feedback
         "@[Nothing to select for @[%a@]@ %s unreachable stmt of %a@]"
@@ -194,7 +194,7 @@ let stmt_nodes_to_select pdg stmt =
 
 let select_stmt_computation kf ?(select=empty_db_select kf) stmt mark =
   SlicingParameters.debug ~level:1 "[Register.select_stmt_computation] on stmt %d" stmt.sid;
-  if not (Db.Value.is_reachable_stmt stmt) then
+  if not (Eva.Results.is_reachable stmt) then
     begin
       SlicingParameters.feedback
         "@[Nothing to select for an unreachable stmt of %a@]"
diff --git a/src/plugins/slicing/slicingState.ml b/src/plugins/slicing/slicingState.ml
index 93a4ad676a1..4b9a224a475 100644
--- a/src/plugins/slicing/slicingState.ml
+++ b/src/plugins/slicing/slicingState.ml
@@ -49,7 +49,7 @@ let may_map ~none f = match P.get_option () with
   | Some _ -> f ()
 
 let reset_slicing () =
-  !Db.Value.compute () ;
+  Eva.Analysis.compute () ;
   let initialized = match P.get_option () with | None -> false | Some _ -> true in
   if not initialized then
     SlicingParameters.feedback ~level:1 "initializing slicing ..."
diff --git a/src/plugins/slicing/slicingTransform.ml b/src/plugins/slicing/slicingTransform.ml
index c27b8a15e3b..9a4723f9723 100644
--- a/src/plugins/slicing/slicingTransform.ml
+++ b/src/plugins/slicing/slicingTransform.ml
@@ -234,7 +234,7 @@ module Visibility (SliceName : sig
   let annotation_visible ff_opt stmt annot =
     SlicingParameters.debug ~current:true ~level:2
       "[SlicingTransform.Visibility.annotation_visible] ?";
-    Db.Value.is_reachable_stmt stmt &&
+    Eva.Results.is_reachable stmt &&
     Alarms.find annot = None && (* Always drop alarms: the alarms table
                                    in the new project is not synchronized *)
     match ff_opt with
-- 
GitLab