From 24be0e41cca7376e1f3f25ce3f371b593ec2ef44 Mon Sep 17 00:00:00 2001
From: Basile Desloges <basile.desloges@cea.fr>
Date: Thu, 3 Jun 2021 15:03:49 +0200
Subject: [PATCH] [eacsl] Fix literal string replacements in local init
 arguments

Implementation of caller renaming and literal string replacements in
arguments shared between regular function call and local init.
---
 .../e-acsl/src/code_generator/injector.ml     | 107 +++++++-----------
 1 file changed, 41 insertions(+), 66 deletions(-)

diff --git a/src/plugins/e-acsl/src/code_generator/injector.ml b/src/plugins/e-acsl/src/code_generator/injector.ml
index d9d96e9c8d7..44a7f433c60 100644
--- a/src/plugins/e-acsl/src/code_generator/injector.ml
+++ b/src/plugins/e-acsl/src/code_generator/injector.ml
@@ -37,6 +37,36 @@ let replace_literal_string_in_exp env kf_opt (* None for globals *) e =
   | None -> e, env
   | Some kf -> Literal_observer.subst_all_literals_in_exp env kf e
 
+let replace_literal_strings_in_args env kf_opt (* None for globals *) args =
+  List.fold_right
+    (fun a (args, env) ->
+       let a, env = replace_literal_string_in_exp env kf_opt a in
+       a :: args, env)
+    args
+    ([], env)
+
+(* rewrite names of functions for which we have alternative definitions in the
+   RTL. *)
+let rename_caller ~loc caller args =
+  if Options.Replace_libc_functions.get ()
+  && Functions.RTL.has_rtl_replacement caller.vname then begin
+    (* rewrite names of functions for which we have alternative definitions in
+       the RTL. *)
+    let fvi = Rtl.Symbols.libc_replacement caller in
+    fvi, args
+  end
+  else if Options.Validate_format_strings.get ()
+       && Functions.Libc.is_printf_name caller.vname then
+    (* rewrite names of format functions (such as printf). This case differs
+       from the above because argument list of format functions is extended with
+       an argument describing actual variadic arguments *)
+    (* replacement name, e.g., [printf] -> [__e_acsl_builtin_printf] *)
+    let fvi = Rtl.Symbols.libc_replacement caller in
+    let fmt = Functions.Libc.get_printf_argument_str ~loc caller.vname args in
+    fvi, fmt :: args
+  else
+    caller, args
+
 let rec inject_in_init env kf_opt vi off = function
   | SingleInit e as init ->
     if vi.vglob then Global_observer.add_initializer vi off init;
@@ -64,73 +94,19 @@ let inject_in_local_init loc env kf vi = function
     let env = Env.add_stmt ~post:true env kf store in
     init, env
 
-  | ConsInit (fvi, args, kind)
-    when Options.Validate_format_strings.get ()
-      && Functions.Libc.is_printf_name fvi.vname
-    ->
-    (* rewrite libc function names (e.g., [printf]). *)
-    let name = Functions.RTL.libc_replacement_name fvi.vname in
-    let new_vi = try Builtins.find name with Not_found -> assert false in
-    let fmt = Functions.Libc.get_printf_argument_str ~loc fvi.vname args in
-    ConsInit(new_vi, fmt :: args, kind), env
-
-  | ConsInit (fvi, _, _) as init
-    when Options.Replace_libc_functions.get ()
-      && Functions.RTL.has_rtl_replacement fvi.vname
-    ->
-    (* rewrite names of functions for which we have alternative definitions in
-       the RTL. *)
-    fvi.vname <- Functions.RTL.libc_replacement_name fvi.vname;
-    init, env
+  | ConsInit (caller, args, kind) ->
+    let args, env = replace_literal_strings_in_args env (Some kf) args in
+    let caller, args = rename_caller ~loc caller args in
+    ConsInit(caller, args, kind), env
 
   | AssignInit init ->
     let init, env = inject_in_init env (Some kf) vi NoOffset init in
     AssignInit init, env
 
-  | ConsInit(vi, l, ck) ->
-    let l, env =
-      List.fold_right
-        (fun e (l, env) ->
-           let e, env = replace_literal_string_in_exp env (Some kf) e in
-           e :: l, env)
-        l
-        ([], env)
-    in
-    ConsInit(vi, l, ck), env
-
 (* ************************************************************************** *)
 (* Instructions and statements *)
 (* ************************************************************************** *)
 
-(* rewrite names of functions for which we have alternative definitions in the
-   RTL. *)
-let rename_caller loc args exp = match exp.enode with
-  | Lval(Var vi, _)
-    when Options.Replace_libc_functions.get ()
-      && Functions.RTL.has_rtl_replacement vi.vname
-    ->
-    vi.vname <- Functions.RTL.libc_replacement_name vi.vname;
-    exp, args
-
-  | Lval(Var vi, _)
-    when Options.Validate_format_strings.get ()
-      && Functions.Libc.is_printf_name vi.vname
-    ->
-    (* rewrite names of format functions (such as printf). This case differs
-       from the above because argument list of format functions is extended with
-       an argument describing actual variadic arguments *)
-    (* replacement name, e.g., [printf] -> [__e_acsl_builtin_printf] *)
-    let name = Functions.RTL.libc_replacement_name vi.vname in
-    (* variadic arguments descriptor *)
-    let fmt = Functions.Libc.get_printf_argument_str ~loc vi.vname args in
-    (* get the library function we need. Cannot just rewrite the name as AST
-       check will then fail *)
-    let vi = try Rtl.Symbols.find_vi name with Not_found -> assert false in
-    Cil.evar vi, fmt :: args
-
-  | _ ->
-    exp, args
-
 (* TODO: should be better documented *)
 let add_initializer loc ?vi lv ?(post=false) stmt env kf =
   if Functions.instrument kf then
@@ -167,15 +143,14 @@ let inject_in_instr env kf stmt = function
     Set(lv, e, loc), env
 
   | Call(result, caller, args, loc) ->
-    let args, env =
-      List.fold_right
-        (fun a (args, env) ->
-           let a, env = replace_literal_string_in_exp env (Some kf) a in
-           a :: args, env)
-        args
-        ([], env)
+    let args, env = replace_literal_strings_in_args env (Some kf) args in
+    let caller, args =
+      match caller.enode with
+      | Lval (Var fvi, _) ->
+        let fvi, args = rename_caller loc fvi args in
+        Cil.evar fvi, args
+      | _ -> caller, args
     in
-    let caller, args = rename_caller loc args caller in
     (* add statement tracking initialization of return values *)
     let env =
       match result with
-- 
GitLab