From 950e347b0cf40cf7a3a35d19e7c7ba9275ad10e1 Mon Sep 17 00:00:00 2001
From: Julien Signoles <julien.signoles@cea.fr>
Date: Fri, 4 Jan 2013 12:52:05 +0000
Subject: [PATCH] [E-ACSL] fixed bugs when calling 'generate_code' dynamically.
 BTW change the plug-in name of dynamic function

---
 src/plugins/e-acsl/main.ml         | 146 ++++++++++++++++-------------
 src/plugins/e-acsl/pre_analysis.ml |   3 +-
 2 files changed, 84 insertions(+), 65 deletions(-)

diff --git a/src/plugins/e-acsl/main.ml b/src/plugins/e-acsl/main.ml
index c83015710ed..b567d0e3955 100644
--- a/src/plugins/e-acsl/main.ml
+++ b/src/plugins/e-acsl/main.ml
@@ -43,6 +43,67 @@ let check =
     (Datatype.func Datatype.unit Datatype.bool)
     check
 
+module Extended_ast =
+  State_builder.Option_ref
+    (Project.Datatype)
+    (struct
+      let name = "E-ACSL AST is extended"
+      let dependencies = []
+     end)
+
+let unmemoized_extend_ast () =
+  let extend () =
+    Kernel.CppExtraArgs.add
+      (Pretty_utils.sfprintf " -I%s/libc" Config.datadir);
+    Kernel.Keep_unused_specified_functions.off ();
+    let register s =
+      File.pre_register
+	(File.NeedCPP 
+	   (s, 
+	    File.get_preprocessor_command () 
+	    ^ Pretty_utils.sfprintf " -I%s" 
+	      (Options.Share.dir ~error:true ())))
+    in
+    List.iter register (Misc.library_files ())
+  in
+  if Ast.is_computed () then begin
+    (* do not modify the existing project: work on a copy.
+       Must also extend the current AST with the E-ACSL's library files. *)
+    let name = Project.get_name (Project.current ()) in
+    let tmpfile = 
+      Extlib.temp_file_cleanup_at_exit ("e_acsl_" ^ name) ".i" in
+    let cout = open_out tmpfile in
+    let fmt = Format.formatter_of_out_channel cout in
+    File.pretty_ast ~fmt ();
+    let selection = 
+      State_selection.diff
+	State_selection.full
+	(State_selection.with_dependencies Ast.self)
+    in
+    let prj =
+      Project.create_by_copy
+	~selection
+	(Pretty_utils.sfprintf "%s for E-ACSL" name)
+    in
+    Project.on prj
+      (fun () ->
+	Kernel.Files.set [ tmpfile ];
+	extend ())
+      ();
+    prj
+  end else begin
+    extend ();
+    Project.current ()
+  end
+
+let extend_ast () = Extended_ast.memo unmemoized_extend_ast
+
+let apply_on_e_acsl_ast f x =
+  let tmp_prj = extend_ast () in
+  let res = Project.on tmp_prj f x in
+  if tmp_prj != Project.current () then Project.remove ~project:tmp_prj ();
+  res
+
 module Resulting_projects =
   State_builder.Hashtbl
     (Datatype.String.Hashtbl)
@@ -58,15 +119,19 @@ let () = Env.global_state := Resulting_projects.self
 let generate_code =
   Resulting_projects.memo
     (fun name ->
-      Pre_analysis.reset ();
-      let visit prj = Visit.do_visit ~prj true in
-      let prj = File.create_project_from_visitor name visit in
-      Resulting_projects.mark_as_computed ();
-      prj)
+      apply_on_e_acsl_ast
+	(fun () ->
+	  Pre_analysis.init_mpz ();
+	  Pre_analysis.reset ();
+	  let visit prj = Visit.do_visit ~prj true in
+	  let prj = File.create_project_from_visitor name visit in
+	  Resulting_projects.mark_as_computed ();
+	  prj)
+	())
 
 let generate_code =
   Dynamic.register
-    ~plugin:"e-acsl"
+    ~plugin:"E_ACSL"
     ~journalize:true
     "generate_code"
     (Datatype.func Datatype.string Project.ty)
@@ -74,75 +139,28 @@ let generate_code =
 
 let predicate_to_exp =
   Dynamic.register
-    ~plugin:"e-acsl"
+    ~plugin:"E_ACSL"
     ~journalize:false
     "predicate_to_exp"
     (Datatype.func2
        Kernel_function.ty Cil_datatype.Predicate_named.ty Cil_datatype.Exp.ty)
     Translate.predicate_to_exp
 
-let analyzed_project = ref None
-
-let add_e_acsl_library _files =
-  analyzed_project := None;
-  if Options.must_visit () && not (Resulting_projects.is_computed ()) then begin
-    let extend () =
-      Kernel.CppExtraArgs.add
-	(Pretty_utils.sfprintf " -I%s/libc" Config.datadir);
-      Kernel.Keep_unused_specified_functions.off ();
-      let register s =
-	File.pre_register
-	  (File.NeedCPP 
-	     (s, 
-	      File.get_preprocessor_command () 
-	      ^ Pretty_utils.sfprintf " -I%s" 
-		(Options.Share.dir ~error:true ())))
-      in
-      List.iter register (Misc.library_files ())
-    in
-    if Ast.is_computed () then begin
-      (* do not modify the existing project: work on a copy.
-	 Must also extend the current AST with the E-ACSL's library files. *)
-      let name = Project.get_name (Project.current ()) in
-      let tmpfile = 
-	Extlib.temp_file_cleanup_at_exit ("e_acsl_" ^ name) ".i" in
-      let cout = open_out tmpfile in
-      let fmt = Format.formatter_of_out_channel cout in
-      File.pretty_ast ~fmt ();
-      let selection = 
-	State_selection.diff
-	  State_selection.full
-	  (State_selection.with_dependencies Ast.self)
-      in
-      let prj =
-	Project.create_by_copy
-	  ~selection
-	  (Pretty_utils.sfprintf "%s for E-ACSL" name)
-      in
-      Project.on prj
-	(fun () ->
-	  Kernel.Files.set [ tmpfile ];
-	  extend ())
-	();
-      analyzed_project := Some prj
-    end else
-      extend ()
-  end
- 
+let add_e_acsl_library _files = 
+  if Options.must_visit () then ignore (extend_ast ())
+
 let () = Cmdline.run_after_configuring_stage add_e_acsl_library
 
-let analyze () =
-  if Options.must_visit () then Pre_analysis.init_mpz ();
+let main () =
   if Options.Run.get () then
     ignore (generate_code (Options.Project_name.get ()))
   else
-    if Options.Check.get () then ignore (check ())
-
-let main () = match !analyzed_project with
-  | None -> analyze ()
-  | Some project -> 
-    Project.on project analyze ();
-    Project.remove ~project ()
+    if Options.Check.get () then
+      apply_on_e_acsl_ast
+	(fun () -> 
+	  Pre_analysis.init_mpz ();
+	  ignore (check ()))
+	()
 
 let () = Db.Main.extend main
 
diff --git a/src/plugins/e-acsl/pre_analysis.ml b/src/plugins/e-acsl/pre_analysis.ml
index 7e1b00a0851..c9f058b3c37 100644
--- a/src/plugins/e-acsl/pre_analysis.ml
+++ b/src/plugins/e-acsl/pre_analysis.ml
@@ -502,7 +502,8 @@ let must_model_vi ?kf ?stmt vi =
   | Some _, None ->
     assert false
   | Some stmt, Some kf  ->
-    assert (Env.is_consolidated ());
+    if not (Env.is_consolidated ()) then 
+      ignore (consolidated_must_model_vi ~kf vi);
     let tbl = 
       try Env.find kf 
       with Not_found -> 
-- 
GitLab