diff --git a/.Makefile.lint b/.Makefile.lint
index 80fb691a8370490eea2a7db9b60c1fae64ab498a..06c49f05b54e16d5f35a24cb731e80fef8f5784f 100644
--- a/.Makefile.lint
+++ b/.Makefile.lint
@@ -344,10 +344,3 @@ ML_LINT_KO+=src/plugins/variadic/standard.ml
 ML_LINT_KO+=src/plugins/variadic/translate.ml
 ML_LINT_KO+=src/plugins/variadic/va_build.ml
 ML_LINT_KO+=src/plugins/variadic/va_types.mli
-ML_LINT_KO+=src/plugins/e-acsl/src/analyses/mmodel_analysis.ml
-ML_LINT_KO+=src/plugins/e-acsl/src/analyses/rte.ml
-ML_LINT_KO+=src/plugins/e-acsl/src/code_generator/at_with_lscope.ml
-ML_LINT_KO+=src/plugins/e-acsl/src/code_generator/at_with_lscope.mli
-ML_LINT_KO+=src/plugins/e-acsl/src/code_generator/temporal.ml
-ML_LINT_KO+=src/plugins/e-acsl/src/code_generator/temporal.mli
-
diff --git a/src/plugins/e-acsl/Makefile.in b/src/plugins/e-acsl/Makefile.in
index a44d27242911d78ca3342a8cac5779d96a85f5d7..06edca935965881a93c24f23401dc0211922ed8e 100644
--- a/src/plugins/e-acsl/Makefile.in
+++ b/src/plugins/e-acsl/Makefile.in
@@ -64,7 +64,8 @@ SRC_ANALYSES:=$(addprefix src/analyses/, $(SRC_ANALYSES))
 
 # code generator
 SRC_CODE_GENERATOR:= \
-	constructor \
+	smart_exp \
+	smart_stmt \
 	gmp \
 	label \
 	env \
diff --git a/src/plugins/e-acsl/doc/Changelog b/src/plugins/e-acsl/doc/Changelog
index caec156e2bce6ce838c1bb9d1c4957685e808264..541d6252e8d8b64cc742d235bc164582829e1afc 100644
--- a/src/plugins/e-acsl/doc/Changelog
+++ b/src/plugins/e-acsl/doc/Changelog
@@ -26,8 +26,8 @@ Plugin E-ACSL <next-release>
 ############################
 
 -* E-ACSL       [2020-08-28] Fix crash that may occur when translating
-	        properties that have been proved valid by another plug-in
-	        (frama-c/e-acsl#106).
+                properties that have been proved valid by another plug-in
+                (frama-c/e-acsl#106).
 -! E-ACSL       [2020-08-28] Remove option -e-acsl-prepare-ast.
 -! E-ACSL       [2020-08-28] Remove option -e-acsl-check.
 -  E-ACSL       [2020-08-07] Add support for logical array comparison
diff --git a/src/plugins/e-acsl/headers/header_spec.txt b/src/plugins/e-acsl/headers/header_spec.txt
index 41708b793a5ad7c2b97a1cf4fb703068e7457a1f..f5d1c3fe39a487370af0db226395887366102ade 100644
--- a/src/plugins/e-acsl/headers/header_spec.txt
+++ b/src/plugins/e-acsl/headers/header_spec.txt
@@ -52,8 +52,6 @@ src/analyses/typing.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/analyses/typing.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/at_with_lscope.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/at_with_lscope.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
-src/code_generator/constructor.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
-src/code_generator/constructor.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/env.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/env.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/global_observer.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
@@ -80,6 +78,10 @@ src/code_generator/quantif.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/quantif.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/rational.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/rational.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
+src/code_generator/smart_exp.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
+src/code_generator/smart_exp.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
+src/code_generator/smart_stmt.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
+src/code_generator/smart_stmt.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/temporal.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/temporal.mli: CEA_LGPL_OR_PROPRIETARY.E_ACSL
 src/code_generator/translate.ml: CEA_LGPL_OR_PROPRIETARY.E_ACSL
diff --git a/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml b/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml
index c480e318b764410dc8acfd272b8c28d27d3f75f6..db85a8c4c96a1d183f0b84ae424531901996fb3d 100644
--- a/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml
+++ b/src/plugins/e-acsl/src/analyses/mmodel_analysis.ml
@@ -138,11 +138,11 @@ end = struct
     try
       Kernel_function.Hashtbl.iter
         (fun _ h ->
-          Stmt.Hashtbl.iter
-            (fun _ set -> match set with
-            | None -> ()
-            | Some s -> if not (Varinfo.Hptset.is_empty s) then raise Exit)
-            h)
+           Stmt.Hashtbl.iter
+             (fun _ set -> match set with
+                | None -> ()
+                | Some s -> if not (Varinfo.Hptset.is_empty s) then raise Exit)
+             h)
         tbl;
       true
     with Exit ->
@@ -162,7 +162,7 @@ let reset () =
 
 module rec Transfer
   : Dataflow.BackwardsTransfer with type t = Varinfo.Hptset.t option
-  = struct
+= struct
 
   let name = "E_ACSL.Pre_analysis"
 
@@ -217,8 +217,8 @@ module rec Transfer
   let rec base_addr_node = function
     | Lval lv | AddrOf lv | StartOf lv ->
       (match lv with
-      | Var vi, _ -> Some vi
-      | Mem e, _ -> base_addr e)
+       | Var vi, _ -> Some vi
+       | Mem e, _ -> base_addr e)
     | BinOp((PlusPI | IndexPI | MinusPI), e1, e2, _) ->
       if is_ptr_or_array_exp e1 then base_addr e1
       else begin
@@ -227,7 +227,7 @@ module rec Transfer
       end
     | Info(e, _) | CastE(_, e) -> base_addr e
     | BinOp((MinusPP | PlusA | MinusA | Mult | Div | Mod |Shiftlt | Shiftrt
-                | Lt | Gt | Le | Ge | Eq | Ne | BAnd | BXor | BOr | LAnd | LOr),
+            | Lt | Gt | Le | Ge | Eq | Ne | BAnd | BXor | BOr | LAnd | LOr),
             _, _, _)
     | UnOp _ | Const _ | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _
     | AlignOfE _ ->
@@ -314,20 +314,20 @@ module rec Transfer
       register_term kf varinfos t2
     | TBinOp((PlusPI | IndexPI | MinusPI), t1, t2) ->
       (match t1.term_type with
-      | Ctype ty when is_ptr_or_array ty -> register_term kf varinfos t1
-      | _ ->
-        match t2.term_type with
-        | Ctype ty when is_ptr_or_array ty -> register_term kf varinfos t2
-        | _ ->
-          if Misc.is_set_of_ptr_or_array t1.term_type ||
-             Misc.is_set_of_ptr_or_array t2.term_type then
-            (* Occurs for example from:
-              \valid(&multi_dynamic[2..4][1..7])
-              where multi_dynamic has been dynamically allocated *)
-            let varinfos = register_term kf varinfos t1 in
-            register_term kf varinfos t2
-          else
-            assert false)
+       | Ctype ty when is_ptr_or_array ty -> register_term kf varinfos t1
+       | _ ->
+         match t2.term_type with
+         | Ctype ty when is_ptr_or_array ty -> register_term kf varinfos t2
+         | _ ->
+           if Misc.is_set_of_ptr_or_array t1.term_type ||
+              Misc.is_set_of_ptr_or_array t2.term_type then
+             (* Occurs for example from:
+                \valid(&multi_dynamic[2..4][1..7])
+                where multi_dynamic has been dynamically allocated *)
+             let varinfos = register_term kf varinfos t1 in
+             register_term kf varinfos t2
+           else
+             assert false)
     | TConst _ | TSizeOf _ | TSizeOfE _ | TSizeOfStr _ | TAlignOf _
     | TAlignOfE _ | Tnull | Ttype _ | TUnOp _ | TBinOp _ ->
       varinfos
@@ -359,73 +359,73 @@ module rec Transfer
   let register_object kf state_ref = object
     inherit Visitor.frama_c_inplace
     method !vpredicate_node = function
-    | Pvalid(_, t) | Pvalid_read(_, t)
-    | Pobject_pointer(_, t) | Pvalid_function t
-    | Pinitialized(_, t) | Pfreeable(_, t) ->
-      (*	Options.feedback "REGISTER %a" Cil.d_term t;*)
-      state_ref := register_term kf !state_ref t;
-      Cil.DoChildren
-    | Pallocable _ -> Error.not_yet "\\allocable"
-    | Pfresh _ -> Error.not_yet "\\fresh"
-    | Pseparated _ -> Error.not_yet "\\separated"
-    | Pdangling _ -> Error.not_yet "\\dangling"
-    | Ptrue | Pfalse | Papp _ | Prel _
-    | Pand _ | Por _ | Pxor _ | Pimplies _ | Piff _ | Pnot _ | Pif _
-    | Pforall _ | Pexists _ | Pat _ ->
-      Cil.DoChildren
-    | Plet(li, _) ->
-      if may_alias li then Error.not_yet "let-binding on array or pointer"
-      else begin
-        state_ref := register_term kf !state_ref (Misc.term_of_li li);
+      | Pvalid(_, t) | Pvalid_read(_, t)
+      | Pobject_pointer(_, t) | Pvalid_function t
+      | Pinitialized(_, t) | Pfreeable(_, t) ->
+        (*	Options.feedback "REGISTER %a" Cil.d_term t;*)
+        state_ref := register_term kf !state_ref t;
         Cil.DoChildren
-      end
+      | Pallocable _ -> Error.not_yet "\\allocable"
+      | Pfresh _ -> Error.not_yet "\\fresh"
+      | Pseparated _ -> Error.not_yet "\\separated"
+      | Pdangling _ -> Error.not_yet "\\dangling"
+      | Ptrue | Pfalse | Papp _ | Prel _
+      | Pand _ | Por _ | Pxor _ | Pimplies _ | Piff _ | Pnot _ | Pif _
+      | Pforall _ | Pexists _ | Pat _ ->
+        Cil.DoChildren
+      | Plet(li, _) ->
+        if may_alias li then Error.not_yet "let-binding on array or pointer"
+        else begin
+          state_ref := register_term kf !state_ref (Misc.term_of_li li);
+          Cil.DoChildren
+        end
     method !vterm term = match term.term_node with
-    | Tbase_addr(_, t) | Toffset(_, t) | Tblock_length(_, t) | Tlet(_, t) ->
-      state_ref := register_term kf !state_ref t;
-      Cil.DoChildren
-    | TConst _ | TSizeOf _ | TSizeOfStr _ | TAlignOf _  | Tnull | Ttype _
-    | Tempty_set ->
-      (* no left-value inside inside: skip for efficiency *)
-      Cil.SkipChildren
-    | TUnOp _ | TBinOp _ | Ttypeof _ | TSizeOfE _
-    | TLval _ | TAlignOfE _ | TCastE _ | TAddrOf _
-    | TStartOf _ | Tapp _ | Tlambda _ | TDataCons _ | Tif _ | Tat _
-    | TUpdate _ | Tunion _ | Tinter _
-    | Tcomprehension _ | Trange _ | TLogic_coerce _ ->
-      (* potential sub-term inside *)
-      Cil.DoChildren
+      | Tbase_addr(_, t) | Toffset(_, t) | Tblock_length(_, t) | Tlet(_, t) ->
+        state_ref := register_term kf !state_ref t;
+        Cil.DoChildren
+      | TConst _ | TSizeOf _ | TSizeOfStr _ | TAlignOf _  | Tnull | Ttype _
+      | Tempty_set ->
+        (* no left-value inside inside: skip for efficiency *)
+        Cil.SkipChildren
+      | TUnOp _ | TBinOp _ | Ttypeof _ | TSizeOfE _
+      | TLval _ | TAlignOfE _ | TCastE _ | TAddrOf _
+      | TStartOf _ | Tapp _ | Tlambda _ | TDataCons _ | Tif _ | Tat _
+      | TUpdate _ | Tunion _ | Tinter _
+      | Tcomprehension _ | Trange _ | TLogic_coerce _ ->
+        (* potential sub-term inside *)
+        Cil.DoChildren
     method !vlogic_label _ = Cil.SkipChildren
     method !vterm_lhost = function
-    | TMem t ->
-      (* potential RTE *)
-      state_ref := register_term kf !state_ref t;
-      Cil.DoChildren
-    | TVar _ | TResult _ ->
-      Cil.SkipChildren
+      | TMem t ->
+        (* potential RTE *)
+        state_ref := register_term kf !state_ref t;
+        Cil.DoChildren
+      | TVar _ | TResult _ ->
+        Cil.SkipChildren
   end
 
-let register_predicate kf pred state =
-  let state_ref = ref state in
-  Error.handle
-    (fun () ->
-      ignore
-        (Visitor.visitFramacIdPredicate (register_object kf state_ref) pred))
-    ();
-  !state_ref
+  let register_predicate kf pred state =
+    let state_ref = ref state in
+    Error.handle
+      (fun () ->
+         ignore
+           (Visitor.visitFramacIdPredicate (register_object kf state_ref) pred))
+      ();
+    !state_ref
 
   let register_code_annot kf a state =
     let state_ref = ref state in
     Error.handle
       (fun () ->
-        ignore
-          (Visitor.visitFramacCodeAnnotation (register_object kf state_ref) a))
+         ignore
+           (Visitor.visitFramacCodeAnnotation (register_object kf state_ref) a))
       ();
     !state_ref
 
-    let rec do_init vi init state = match init with
-      | SingleInit e -> handle_assignment state (Var vi, NoOffset) e
-      | CompoundInit(_, l) ->
-        List.fold_left (fun state (_, init) -> do_init vi init state) state l
+  let rec do_init vi init state = match init with
+    | SingleInit e -> handle_assignment state (Var vi, NoOffset) e
+    | CompoundInit(_, l) ->
+      List.fold_left (fun state (_, init) -> do_init vi init state) state l
 
   let register_initializers state =
     let do_one vi init state = match init.init with
@@ -433,9 +433,9 @@ let register_predicate kf pred state =
       | Some init -> do_init vi init state
     in
     Globals.Vars.fold_in_file_rev_order do_one state
-(* below: compatibility with Fluorine *)
-(*    let l = Globals.Vars.fold_in_file_order (fun v i l -> (v, i) :: l) [] in
-    List.fold_left (fun state (v, i) -> do_one v i state) state l*)
+  (* below: compatibility with Fluorine *)
+  (*    let l = Globals.Vars.fold_in_file_order (fun v i l -> (v, i) :: l) [] in
+        List.fold_left (fun state (v, i) -> do_one v i state) state l*)
 
   (** The (backwards) transfer function for a branch. The [(Cil.CurrentLoc.get
       ())] is set before calling this. If it returns None, then we have some
@@ -447,59 +447,63 @@ let register_predicate kf pred state =
     let is_last = Kernel_function.is_return_stmt kf stmt in
     Dataflow.Post
       (fun state ->
-        let state = Env.default_varinfos state in
-        let state =
-          if Functions.check kf then
-            let state =
-              if (is_first || is_last) && Functions.RTL.is_generated_kf kf then
-                Annotations.fold_behaviors
-                  (fun _ bhv s ->
-                    let handle_annot test f s =
-                      if test then
-                        f
-                          (fun _ p s -> register_predicate kf p s)
-                          kf
-                          bhv.b_name
+         let state = Env.default_varinfos state in
+         let state =
+           if Functions.check kf then
+             let state =
+               if (is_first || is_last) && Functions.RTL.is_generated_kf kf then
+                 Annotations.fold_behaviors
+                   (fun _ bhv s ->
+                      let handle_annot test f s =
+                        if test then
+                          f
+                            (fun _ p s -> register_predicate kf p s)
+                            kf
+                            bhv.b_name
+                            s
+                        else
                           s
-                      else
-                        s
-                  in
-                    let s = handle_annot is_first Annotations.fold_requires s in
-                    let s = handle_annot is_first Annotations.fold_assumes s in
-                    handle_annot
-                      is_last
-                      (fun f ->
-                        Annotations.fold_ensures (fun e (_, p) -> f e p)) s)
-                  kf
-                  state
-              else
-                state
-            in
-            let state =
-              Annotations.fold_code_annot
-                (fun _ -> register_code_annot kf) stmt state
-            in
-            if stmt.ghost then
-              let rtes = Rte.stmt kf stmt in
-              List.fold_left
-                (fun state a -> register_code_annot kf a state) state rtes
-            else
-              state
-          else (* not (Options.Functions.check kf): do not monitor [kf] *)
-            state
-        in
-        let state =
-        (* take initializers into account *)
-          if is_first then
-            let main, lib = Globals.entry_point () in
-            if Kernel_function.equal kf main && not lib then
-              register_initializers state
-            else
-              state
-          else
-            state
-        in
-        Some state)
+                      in
+                      let s =
+                        handle_annot is_first Annotations.fold_requires s
+                      in
+                      let s =
+                        handle_annot is_first Annotations.fold_assumes s
+                      in
+                      handle_annot
+                        is_last
+                        (fun f ->
+                           Annotations.fold_ensures (fun e (_, p) -> f e p)) s)
+                   kf
+                   state
+               else
+                 state
+             in
+             let state =
+               Annotations.fold_code_annot
+                 (fun _ -> register_code_annot kf) stmt state
+             in
+             if stmt.ghost then
+               let rtes = Rte.stmt kf stmt in
+               List.fold_left
+                 (fun state a -> register_code_annot kf a state) state rtes
+             else
+               state
+           else (* not (Options.Functions.check kf): do not monitor [kf] *)
+             state
+         in
+         let state =
+           (* take initializers into account *)
+           if is_first then
+             let main, lib = Globals.entry_point () in
+             if Kernel_function.equal kf main && not lib then
+               register_initializers state
+             else
+               state
+           else
+             state
+         in
+         Some state)
 
   let do_call res f args state =
     let kf = Globals.Functions.get f in
@@ -512,11 +516,11 @@ let register_predicate kf pred state =
           let init =
             List.fold_left2
               (fun acc p a -> match base_addr a with
-              | None -> acc
-              | Some vi ->
-                if Varinfo.Hptset.mem vi state
-                then Varinfo.Hptset.add p acc
-                else acc)
+                 | None -> acc
+                 | Some vi ->
+                   if Varinfo.Hptset.mem vi state
+                   then Varinfo.Hptset.add p acc
+                   else acc)
               state
               params
               args
@@ -536,10 +540,10 @@ let register_predicate kf pred state =
              corresponding formals must be kept *)
           List.fold_left2
             (fun acc p a -> match base_addr a with
-            | None -> acc
-            | Some vi ->
-              if Varinfo.Hptset.mem p state then Varinfo.Hptset.add vi acc
-              else acc)
+               | None -> acc
+               | Some vi ->
+                 if Varinfo.Hptset.mem p state then Varinfo.Hptset.add vi acc
+                 else acc)
             state
             params
             args
@@ -589,19 +593,19 @@ let register_predicate kf pred state =
       do_call (Some (Cil.var v)) f args state
     | Call(result, f_exp, l, _) ->
       (match f_exp.enode with
-      | Lval(Var vi, NoOffset) -> do_call result vi l state
-      | _ ->
-        Options.warning ~current:true
-          "function pointers may introduce too limited instrumentation.";
-(* imprecise function call: keep each argument *)
-        Dataflow.Done
-          (Some
-             (List.fold_left
-                (fun acc e -> match base_addr e with
-                | None -> acc
-                | Some vi -> Varinfo.Hptset.add vi acc)
-                state
-                l)))
+       | Lval(Var vi, NoOffset) -> do_call result vi l state
+       | _ ->
+         Options.warning ~current:true
+           "function pointers may introduce too limited instrumentation.";
+         (* imprecise function call: keep each argument *)
+         Dataflow.Done
+           (Some
+              (List.fold_left
+                 (fun acc e -> match base_addr e with
+                    | None -> acc
+                    | Some vi -> Varinfo.Hptset.add vi acc)
+                 state
+                 l)))
     | Asm _ -> Error.not_yet "asm"
     | Skip _ | Code_annot _ -> Dataflow.Default
 
@@ -633,23 +637,25 @@ end = struct
        if is_init then
          Extlib.may
            (fun set ->
-             List.iter
-               (fun s ->
-                 let old =
-                   try Extlib.the (Stmt.Hashtbl.find tbl s)
-                   with Not_found -> assert false
-                 in
-                 Stmt.Hashtbl.replace
-                   tbl
-                   s
-                   (Some (Varinfo.Hptset.union set old)))
-               returns)
+              List.iter
+                (fun s ->
+                   let old =
+                     try Extlib.the (Stmt.Hashtbl.find tbl s)
+                     with Not_found -> assert false
+                   in
+                   Stmt.Hashtbl.replace
+                     tbl
+                     s
+                     (Some (Varinfo.Hptset.union set old)))
+                returns)
            init_set
        else begin
          List.iter (fun s -> Stmt.Hashtbl.add tbl s None) stmts;
          Extlib.may
            (fun set ->
-             List.iter (fun s -> Stmt.Hashtbl.replace tbl s (Some set)) returns)
+              List.iter
+                (fun s -> Stmt.Hashtbl.replace tbl s (Some set))
+                returns)
            init_set
        end;
        D.compute stmts
@@ -665,12 +671,12 @@ end = struct
     else
       try
         let stmt = Kernel_function.find_first_stmt kf in
-(*      Options.feedback "GETTING %a" Kernel_function.pretty kf;*)
+        (*      Options.feedback "GETTING %a" Kernel_function.pretty kf;*)
         let tbl =
           if Env.mem_init kf init then
             try Env.find kf with Not_found -> assert false
           else begin
-    (* WARN: potentially incorrect in case of recursive call *)
+            (* WARN: potentially incorrect in case of recursive call *)
             Env.add_init kf init;
             Env.apply (compute init) kf
           end
@@ -691,16 +697,18 @@ let consolidated_must_model_vi vi =
     Env.consolidated_mem vi
   else begin
     Options.feedback ~level:2 "performing pre-analysis for minimal memory \
-instrumentation.";
+                               instrumentation.";
     (try
        let main, _ = Globals.entry_point () in
        let set = Compute.get main in
        Env.consolidate set
      with Globals.No_such_entry_point s ->
-       Options.warning ~once:true "%s@ \
-@[The generated program may miss memory instrumentation@ \
-if there are memory-related annotations.@]"
- s);
+       Options.warning
+         ~once:true
+         "%s@ \
+          @[The generated program may miss memory instrumentation@ \
+          if there are memory-related annotations.@]"
+         s);
     Options.feedback ~level:2 "pre-analysis done.";
     Env.consolidated_mem vi
   end
@@ -715,24 +723,24 @@ let must_model_vi ?kf ?stmt vi =
      TODO: could be optimized though *)
   consolidated_must_model_vi vi
 (*  match stmt, kf with
-  | None, _ -> consolidated_must_model_vi vi
-  | Some _, None ->
+    | None, _ -> consolidated_must_model_vi vi
+    | Some _, None ->
     assert false
-  | Some stmt, Some kf  ->
+    | Some stmt, Some kf  ->
     if not (Env.is_consolidated ()) then
       ignore (consolidated_must_model_vi vi);
     try
       let tbl = Env.find kf in
       try
-let set = Stmt.Hashtbl.find tbl stmt in
-Varinfo.Hptset.mem vi (Env.default_varinfos set)
+    let set = Stmt.Hashtbl.find tbl stmt in
+    Varinfo.Hptset.mem vi (Env.default_varinfos set)
       with Not_found ->
-(* new statement *)
-consolidated_must_model_vi vi
+    (* new statement *)
+    consolidated_must_model_vi vi
     with Not_found ->
       (* [kf] is dead code *)
       false
- *)
+*)
 
 let rec apply_on_vi_base_from_lval f ?kf ?stmt = function
   | Var vi, _ -> f ?kf ?stmt vi
@@ -748,7 +756,7 @@ and apply_on_vi_base_from_exp f ?kf ?stmt e = match e.enode with
     || apply_on_vi_base_from_exp f ?kf ?stmt e2
   | Info(e, _) | CastE(_, e) -> apply_on_vi_base_from_exp f ?kf ?stmt e
   | BinOp((PlusA | MinusA | Mult | Div | Mod |Shiftlt | Shiftrt | Lt | Gt | Le
-            | Ge | Eq | Ne | BAnd | BXor | BOr | LAnd | LOr), _, _, _)
+          | Ge | Eq | Ne | BAnd | BXor | BOr | LAnd | LOr), _, _, _)
   | Const _ -> (* possible in case of static address *) false
   | UnOp _ | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _ | AlignOfE _ ->
     Options.fatal "[pre_analysis] unexpected expression %a" Exp.pretty e
@@ -777,20 +785,20 @@ let must_never_monitor_exp ?kf ?stmt lv  =
 let must_model_vi ?kf ?stmt vi =
   not (must_never_monitor vi)
   &&
-    (Options.Full_mmodel.get ()
-     || Error.generic_handle (must_model_vi ?kf ?stmt) false vi)
+  (Options.Full_mmodel.get ()
+   || Error.generic_handle (must_model_vi ?kf ?stmt) false vi)
 
 let must_model_lval ?kf ?stmt lv =
   not (must_never_monitor_lval ?kf ?stmt lv)
   &&
-    (Options.Full_mmodel.get ()
-     || Error.generic_handle (must_model_lval ?kf ?stmt) false lv)
+  (Options.Full_mmodel.get ()
+   || Error.generic_handle (must_model_lval ?kf ?stmt) false lv)
 
 let must_model_exp ?kf ?stmt exp =
   not (must_never_monitor_exp ?kf ?stmt exp)
   &&
-    (Options.Full_mmodel.get ()
-     || Error.generic_handle (must_model_exp ?kf ?stmt) false exp)
+  (Options.Full_mmodel.get ()
+   || Error.generic_handle (must_model_exp ?kf ?stmt) false exp)
 
 let use_model () =
   not (Env.is_empty ())
diff --git a/src/plugins/e-acsl/src/analyses/rte.ml b/src/plugins/e-acsl/src/analyses/rte.ml
index 96a1afbb988346ccc261a2181d097d949b370c8b..9305eff3a55b06c68106628a229bb27afd265565 100644
--- a/src/plugins/e-acsl/src/analyses/rte.ml
+++ b/src/plugins/e-acsl/src/analyses/rte.ml
@@ -27,7 +27,7 @@
 let warn_rte warn exn =
   if warn then
     Options.warning "@[@[cannot run RTE:@ %s.@]@ \
-Ignoring potential runtime errors in annotations." 
+                     Ignoring potential runtime errors in annotations."
       (Printexc.to_string exn)
 
 (* ************************************************************************** *)
@@ -45,8 +45,8 @@ let stmt ?(warn=true) =
          (let module L = Datatype.List(Code_annotation) in L.ty))
   with Failure _ | Dynamic.Unbound_value _ | Dynamic.Incompatible_type _ as exn
     ->
-      warn_rte warn exn;
-      fun _ _ -> []
+    warn_rte warn exn;
+    fun _ _ -> []
 
 let exp ?(warn=true) =
   try
@@ -57,8 +57,8 @@ let exp ?(warn=true) =
          (let module L = Datatype.List(Code_annotation) in L.ty))
   with Failure _ | Dynamic.Unbound_value _ | Dynamic.Incompatible_type _ as exn
     ->
-      warn_rte warn exn;
-      fun _ _ _ -> []
+    warn_rte warn exn;
+    fun _ _ _ -> []
 
 (*
 Local Variables:
diff --git a/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml b/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml
index 040c83991edcca505c5758fdf0ad4dea40420c12..671ea306b1f641e8cacba62184345c3256d526fd 100644
--- a/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml
+++ b/src/plugins/e-acsl/src/code_generator/at_with_lscope.ml
@@ -39,8 +39,8 @@ let term_to_exp_ref
 (*****************************************************************************)
 
 (* Remove all the bindings for [kf]. [Cil_datatype.Kf.Hashtbl] does not
-  provide the [remove_all] function. Thus we need to keep calling [remove]
-  until all entries are removed. *)
+   provide the [remove_all] function. Thus we need to keep calling [remove]
+   until all entries are removed. *)
 let rec remove_all tbl kf =
   if Cil_datatype.Kf.Hashtbl.mem tbl kf then begin
     Cil_datatype.Kf.Hashtbl.remove tbl kf;
@@ -66,10 +66,10 @@ end
 (**************************************************************************)
 
 (* Builds the terms [t_size] and [t_shifted] from each
-  [Lvs_quantif(tmin, lv, tmax)] from [lscope]
-  where [t_size = tmax - tmin + (-1|0|1)] depending on whether the
+   [Lvs_quantif(tmin, lv, tmax)] from [lscope]
+   where [t_size = tmax - tmin + (-1|0|1)] depending on whether the
                                           inequalities are strict or large
-  and [t_shifted = lv - tmin + (-1|0)] (so that we start indexing at 0) *)
+   and [t_shifted = lv - tmin + (-1|0)] (so that we start indexing at 0) *)
 let rec sizes_and_shifts_from_quantifs ~loc kf lscope sizes_and_shifts =
   match lscope with
   | [] ->
@@ -97,29 +97,29 @@ let rec sizes_and_shifts_from_quantifs ~loc kf lscope sizes_and_shifts =
     in
     let iv = Interval.(extract_ival (infer t_size)) in
     (* The EXACT amount of memory that is needed can be known at runtime. This
-      is because the tightest bounds for the variables can be known at runtime.
-      Example: In the following predicate
+       is because the tightest bounds for the variables can be known at runtime.
+       Example: In the following predicate
         [\exists integer u; 9 <= u <= 13 &&
          \forall integer v; -5 < v <= (u <= 11 ? u + 6 : u - 9) ==>
            \at(u + v > 0, K)]
         the upper bound [M] for [v] depends on [u].
         In chronological order, [M] equals to 15, 16, 17, 3 and 4.
         Thus the tightest upper bound for [v] is [max(M)=17].
-      HOWEVER, computing that exact information requires extra nested loops,
-      prior to the [malloc] stmts, that will try all the possible values of the
-      variables involved in the bounds.
-      Instead of sacrificing time over memory (by performing these extra
-      computations), we consider that sacrificing memory over time is more
-      beneficial. In particular, though we may allocate more memory than
-      needed, the number of reads/writes into it is the same in both cases.
-      Conclusion: over-approximate [t_size] *)
+       HOWEVER, computing that exact information requires extra nested loops,
+       prior to the [malloc] stmts, that will try all the possible values of the
+       variables involved in the bounds.
+       Instead of sacrificing time over memory (by performing these extra
+       computations), we consider that sacrificing memory over time is more
+       beneficial. In particular, though we may allocate more memory than
+       needed, the number of reads/writes into it is the same in both cases.
+       Conclusion: over-approximate [t_size] *)
     let t_size = match Ival.min_and_max iv with
       | _, Some max ->
         Logic_const.tint ~loc max
       | _, None ->
         Error.not_yet
           "\\at on purely logic variables and with quantifier that uses \
-            too complex bound (E-ACSL cannot infer a finite upper bound to it)"
+           too complex bound (E-ACSL cannot infer a finite upper bound to it)"
     in
     (* Index *)
     let t_lv = Logic_const.tvar ~loc lv in
@@ -148,13 +148,13 @@ let rec sizes_and_shifts_from_quantifs ~loc kf lscope sizes_and_shifts =
 let size_from_sizes_and_shifts ~loc = function
   | [] ->
     (* No quantified variable. But still need to allocate [1*sizeof(_)] amount
-      of memory to store purely logic variables that are NOT quantified
-      (example: from \let). *)
+       of memory to store purely logic variables that are NOT quantified
+       (example: from \let). *)
     Cil.lone ~loc ()
   | (size, _) :: sizes_and_shifts ->
     List.fold_left
       (fun t_size (t_s, _) ->
-        Logic_const.term ~loc (TBinOp(Mult, t_size, t_s)) Linteger)
+         Logic_const.term ~loc (TBinOp(Mult, t_size, t_s)) Linteger)
       size
       sizes_and_shifts
 
@@ -171,35 +171,35 @@ let lval_at_index ~loc kf env (e_at, vi_at, t_index) =
   lval_at_index, env
 
 (* Associate to each possible tuple of quantifiers
-  a unique index from the set {n | 0 <= n < n_max}.
-  That index will serve to identify the memory location where the evaluation
-  of the term/predicate is stored for the given tuple of quantifier.
-  The following gives the smallest set of such indexes (hence we use the
-  smallest amount of memory in some respect):
-  To (t_shifted_n, t_shifted_n-1, ..., t_shifted_1)
-  where 0 <= t_shifted_i < beta_i
-  corresponds: \sum_{i=1}^n( t_shifted_i * \pi_{j=1}^{i-1}(beta_j) ) *)
+   a unique index from the set {n | 0 <= n < n_max}.
+   That index will serve to identify the memory location where the evaluation
+   of the term/predicate is stored for the given tuple of quantifier.
+   The following gives the smallest set of such indexes (hence we use the
+   smallest amount of memory in some respect):
+   To (t_shifted_n, t_shifted_n-1, ..., t_shifted_1)
+   where 0 <= t_shifted_i < beta_i
+   corresponds: \sum_{i=1}^n( t_shifted_i * \pi_{j=1}^{i-1}(beta_j) ) *)
 let index_from_sizes_and_shifts ~loc sizes_and_shifts =
   let product terms = List.fold_left
-    (fun product t ->
-      Logic_const.term ~loc (TBinOp(Mult, product, t)) Linteger)
-    (Cil.lone ~loc ())
-    terms
+      (fun product t ->
+         Logic_const.term ~loc (TBinOp(Mult, product, t)) Linteger)
+      (Cil.lone ~loc ())
+      terms
   in
   let sum, _ = List.fold_left
-    (fun (index, sizes) (t_size, t_shifted) ->
-      let pi_beta_j = product sizes in
-      let bi_mult_pi_beta_j =
-        Logic_const.term ~loc (TBinOp(Mult, t_shifted, pi_beta_j)) Linteger
-      in
-      let sum = Logic_const.term
-        ~loc
-        (TBinOp(PlusA, bi_mult_pi_beta_j, index))
-        Linteger
-      in
-      sum, t_size :: sizes)
-    (Cil.lzero ~loc (), [])
-    sizes_and_shifts
+      (fun (index, sizes) (t_size, t_shifted) ->
+         let pi_beta_j = product sizes in
+         let bi_mult_pi_beta_j =
+           Logic_const.term ~loc (TBinOp(Mult, t_shifted, pi_beta_j)) Linteger
+         in
+         let sum = Logic_const.term
+             ~loc
+             (TBinOp(PlusA, bi_mult_pi_beta_j, index))
+             Linteger
+         in
+         sum, t_size :: sizes)
+      (Cil.lzero ~loc (), [])
+      sizes_and_shifts
   in
   sum
 
@@ -225,62 +225,63 @@ let to_exp ~loc kf env pot label =
   in
   (* Creating the pointer *)
   let ty = match pot with
-  | Lscope.PoT_pred _ ->
-    Cil.intType
-  | Lscope.PoT_term t ->
-    begin match Typing.get_number_ty t with
-    | Typing.(C_integer _ | C_float _ | Nan) ->
-      Typing.get_typ t
-    | Typing.(Rational | Real) ->
-      Error.not_yet "\\at on purely logic variables and over real type"
-    | Typing.Gmpz ->
-      Error.not_yet "\\at on purely logic variables and over gmp type"
-    end
+    | Lscope.PoT_pred _ ->
+      Cil.intType
+    | Lscope.PoT_term t ->
+      begin match Typing.get_number_ty t with
+        | Typing.(C_integer _ | C_float _ | Nan) ->
+          Typing.get_typ t
+        | Typing.(Rational | Real) ->
+          Error.not_yet "\\at on purely logic variables and over real type"
+        | Typing.Gmpz ->
+          Error.not_yet "\\at on purely logic variables and over gmp type"
+      end
   in
   let ty_ptr = TPtr(ty, []) in
   let vi_at, e_at, env = Env.new_var
-    ~loc
-    ~name:"at"
-    ~scope:Varname.Function
-    env
-    kf
-    None
-    ty_ptr
-    (fun vi e ->
-      (* Handle [malloc] and [free] stmts *)
-      let lty_sizeof = Ctype Cil.(theMachine.typeOfSizeOf) in
-      let t_sizeof = Logic_const.term ~loc (TSizeOf ty) lty_sizeof in
-      let t_size = size_from_sizes_and_shifts ~loc sizes_and_shifts in
-      let t_size =
-        Logic_const.term ~loc (TBinOp(Mult, t_sizeof, t_size)) lty_sizeof
-      in
-      Typing.type_term ~use_gmp_opt:false t_size;
-      let malloc_stmt = match Typing.get_number_ty t_size with
-      | Typing.C_integer IInt ->
-        let e_size, _ = term_to_exp kf env t_size in
-        let e_size = Cil.constFold false e_size in
-        let malloc_stmt =
-          Constructor.mk_lib_call ~loc
-            ~result:(Cil.var vi)
-            "malloc"
-            [ e_size ]
-        in
-        malloc_stmt
-      | Typing.(C_integer _ | C_float _ | Gmpz) ->
-        Error.not_yet
-          "\\at on purely logic variables that needs to allocate \
-           too much memory (bigger than int_max bytes)"
-      | Typing.(Rational | Real | Nan) ->
-        Error.not_yet "quantification over non-integer type"
-      in
-      let free_stmt = Constructor.mk_lib_call ~loc "free" [e] in
-      (* The list of stmts returned by the current closure are inserted
-        LOCALLY to the block where the new var is FIRST used, whatever scope
-        is indicated to [Env.new_var].
-        Thus we need to add [malloc] and [free] through dedicated functions. *)
-      Malloc.add kf malloc_stmt;
-      Free.add kf free_stmt;
-      [])
+      ~loc
+      ~name:"at"
+      ~scope:Varname.Function
+      env
+      kf
+      None
+      ty_ptr
+      (fun vi e ->
+         (* Handle [malloc] and [free] stmts *)
+         let lty_sizeof = Ctype Cil.(theMachine.typeOfSizeOf) in
+         let t_sizeof = Logic_const.term ~loc (TSizeOf ty) lty_sizeof in
+         let t_size = size_from_sizes_and_shifts ~loc sizes_and_shifts in
+         let t_size =
+           Logic_const.term ~loc (TBinOp(Mult, t_sizeof, t_size)) lty_sizeof
+         in
+         Typing.type_term ~use_gmp_opt:false t_size;
+         let malloc_stmt = match Typing.get_number_ty t_size with
+           | Typing.C_integer IInt ->
+             let e_size, _ = term_to_exp kf env t_size in
+             let e_size = Cil.constFold false e_size in
+             let malloc_stmt =
+               Smart_stmt.lib_call ~loc
+                 ~result:(Cil.var vi)
+                 "malloc"
+                 [ e_size ]
+             in
+             malloc_stmt
+           | Typing.(C_integer _ | C_float _ | Gmpz) ->
+             Error.not_yet
+               "\\at on purely logic variables that needs to allocate \
+                too much memory (bigger than int_max bytes)"
+           | Typing.(Rational | Real | Nan) ->
+             Error.not_yet "quantification over non-integer type"
+         in
+         let free_stmt = Smart_stmt.lib_call ~loc "free" [e] in
+         (* The list of stmts returned by the current closure are inserted
+            LOCALLY to the block where the new var is FIRST used, whatever scope
+            is indicated to [Env.new_var].
+            Thus we need to add [malloc] and [free] through dedicated functions.
+         *)
+         Malloc.add kf malloc_stmt;
+         Free.add kf free_stmt;
+         [])
   in
   (* Index *)
   let t_index = index_from_sizes_and_shifts ~loc sizes_and_shifts in
@@ -295,34 +296,34 @@ let to_exp ~loc kf env pot label =
       let e, env = named_predicate_to_exp kf env p in
       let e = Cil.constFold false e in
       let storing_stmt =
-        Constructor.mk_assigns ~loc ~result:lval e
+        Smart_stmt.assigns ~loc ~result:lval e
       in
       let block, env =
         Env.pop_and_get env storing_stmt ~global_clear:false Env.After
       in
       (* We CANNOT return [block.bstmts] because it does NOT contain
-        variable declarations. *)
-      [ Constructor.mk_block_stmt block ], env
+         variable declarations. *)
+      [ Smart_stmt.block_stmt block ], env
     | Lscope.PoT_term t ->
       begin match Typing.get_number_ty t with
-      | Typing.(C_integer _ | C_float _ | Nan) ->
-        let env = Env.push env in
-        let lval, env = lval_at_index ~loc kf env (e_at, vi_at, t_index) in
-        let e, env = term_to_exp kf env t in
-        let e = Cil.constFold false e in
-        let storing_stmt =
-         Constructor.mk_assigns ~loc ~result:lval e
-        in
-        let block, env =
-          Env.pop_and_get env storing_stmt ~global_clear:false Env.After
-        in
-        (* We CANNOT return [block.bstmts] because it does NOT contain
-          variable declarations. *)
-        [ Constructor.mk_block_stmt block ], env
-      | Typing.(Rational | Real) ->
-        Error.not_yet "\\at on purely logic variables and over real type"
-      | Typing.Gmpz ->
-        Error.not_yet "\\at on purely logic variables and over gmp type"
+        | Typing.(C_integer _ | C_float _ | Nan) ->
+          let env = Env.push env in
+          let lval, env = lval_at_index ~loc kf env (e_at, vi_at, t_index) in
+          let e, env = term_to_exp kf env t in
+          let e = Cil.constFold false e in
+          let storing_stmt =
+            Smart_stmt.assigns ~loc ~result:lval e
+          in
+          let block, env =
+            Env.pop_and_get env storing_stmt ~global_clear:false Env.After
+          in
+          (* We CANNOT return [block.bstmts] because it does NOT contain
+             variable declarations. *)
+          [ Smart_stmt.block_stmt block ], env
+        | Typing.(Rational | Real) ->
+          Error.not_yet "\\at on purely logic variables and over real type"
+        | Typing.Gmpz ->
+          Error.not_yet "\\at on purely logic variables and over gmp type"
       end
   in
   (* Storing loops *)
@@ -333,16 +334,16 @@ let to_exp ~loc kf env pot label =
   in
   let storing_loops_block = Cil.mkBlock storing_loops_stmts in
   let storing_loops_block, env = Env.pop_and_get
-    env
-    (Constructor.mk_block_stmt storing_loops_block)
-    ~global_clear:false
-    Env.After
+      env
+      (Smart_stmt.block_stmt storing_loops_block)
+      ~global_clear:false
+      Env.After
   in
   (* Put at label *)
   let env = put_block_at_label env kf storing_loops_block label in
   (* Returning *)
   let lval_at_index, env = lval_at_index ~loc kf env (e_at, vi_at, t_index) in
-  let e = Constructor.mk_lval ~loc lval_at_index in
+  let e = Smart_exp.lval ~loc lval_at_index in
   e, env
 
 (*
diff --git a/src/plugins/e-acsl/src/code_generator/at_with_lscope.mli b/src/plugins/e-acsl/src/code_generator/at_with_lscope.mli
index f5b51d739bd4de58a55583a2e68cd2f95696b87e..0a971045fddfe3d0cc9ec1f9a90a6fdf982a46ed 100644
--- a/src/plugins/e-acsl/src/code_generator/at_with_lscope.mli
+++ b/src/plugins/e-acsl/src/code_generator/at_with_lscope.mli
@@ -24,7 +24,7 @@ open Cil_types
 open Cil_datatype
 
 (* Convert \at on terms or predicates in which we can find purely
-  logic variable. *)
+   logic variable. *)
 
 (**************************************************************************)
 (*************************** Translation **********************************)
@@ -39,8 +39,8 @@ val to_exp:
 (*****************************************************************************)
 
 (* The different possible evaluations of the [\at] under study are
-  stored in a memory location that needs to be alloted then freed.
-  This part is designed for that purpose. *)
+   stored in a memory location that needs to be alloted then freed.
+   This part is designed for that purpose. *)
 
 module Malloc: sig
   val find_all: kernel_function -> stmt list
diff --git a/src/plugins/e-acsl/src/code_generator/env.ml b/src/plugins/e-acsl/src/code_generator/env.ml
index e457ac5c2264548399b60b7ed77206f49cd6973e..cfdbe5fdda47bb9b3ea0aab39423b7e26bf8c5c6 100644
--- a/src/plugins/e-acsl/src/code_generator/env.ml
+++ b/src/plugins/e-acsl/src/code_generator/env.ml
@@ -56,7 +56,7 @@ type local_env = {
 type t = {
   lscope: Lscope.t;
   lscope_reset: bool;
-  annotation_kind: Constructor.annotation_kind;
+  annotation_kind: Smart_stmt.annotation_kind;
   new_global_vars: (varinfo * localized_scope) list;
   (* generated variables. The scope indicates the level where the variable
      should be added. *)
@@ -88,7 +88,7 @@ let empty_local_env =
 let empty =
   { lscope = Lscope.empty;
     lscope_reset = true;
-    annotation_kind = Constructor.Assertion;
+    annotation_kind = Smart_stmt.Assertion;
     new_global_vars = [];
     global_mp_tbl = empty_mp_tbl;
     env_stack = [];
@@ -257,7 +257,7 @@ let rtl_call_to_new_var ~loc ?scope ?name env kf t ty func_name args =
       t
       ty
       (fun v _ ->
-         [ Constructor.mk_rtl_call ~loc ~result:(Cil.var v) func_name args ])
+         [ Smart_stmt.rtl_call ~loc ~result:(Cil.var v) func_name args ])
   in
   exp, env
 
@@ -351,9 +351,9 @@ let add_stmt ?(post=false) ?before env kf stmt =
   { env with env_stack = local_env :: tl }
 
 let extend_stmt_in_place env stmt ~label block =
-  let new_stmt = Constructor.mk_block_stmt block in
+  let new_stmt = Smart_stmt.block_stmt block in
   let sk = stmt.skind in
-  stmt.skind <- Block (Cil.mkBlock [ new_stmt; Constructor.mk_stmt sk ]);
+  stmt.skind <- Block (Cil.mkBlock [ new_stmt; Smart_stmt.stmt sk ]);
   let pre = match label with
     | BuiltinLabel(Here | Post) -> true
     | BuiltinLabel(Old | Pre | LoopEntry | LoopCurrent | Init)
@@ -447,7 +447,7 @@ let pop_and_get ?(split=false) env stmt ~global_clear where =
        add the given [stmt] afterwards. This way, we have the guarantee that
        the final block does not contain any local, so may be transient. *)
     if split then
-      let sblock = Constructor.mk_block_stmt b in
+      let sblock = Smart_stmt.block_stmt b in
       Cil.transient_block (Cil.mkBlock [ sblock; stmt ])
     else
       b
diff --git a/src/plugins/e-acsl/src/code_generator/env.mli b/src/plugins/e-acsl/src/code_generator/env.mli
index 847b551cacb7222e4efdf9f1448012bcc655496a..94c11335f1c96bbcee2a1def0150be956bb81435 100644
--- a/src/plugins/e-acsl/src/code_generator/env.mli
+++ b/src/plugins/e-acsl/src/code_generator/env.mli
@@ -148,8 +148,8 @@ end
 (** {2 Current annotation kind} *)
 (* ************************************************************************** *)
 
-val annotation_kind: t -> Constructor.annotation_kind
-val set_annotation_kind: t -> Constructor.annotation_kind -> t
+val annotation_kind: t -> Smart_stmt.annotation_kind
+val set_annotation_kind: t -> Smart_stmt.annotation_kind -> t
 
 (* ************************************************************************** *)
 (** {2 Loop invariants} *)
diff --git a/src/plugins/e-acsl/src/code_generator/global_observer.ml b/src/plugins/e-acsl/src/code_generator/global_observer.ml
index ab1d0ed88db4408e4dd14635e8291350f6666ba8..0e6a3ac2302a17cae489c61671fb46e4f7946ecc 100644
--- a/src/plugins/e-acsl/src/code_generator/global_observer.ml
+++ b/src/plugins/e-acsl/src/code_generator/global_observer.ml
@@ -123,8 +123,8 @@ let mk_init_function () =
          if Misc.is_fc_or_compiler_builtin vi then stmts
          else
            (* a global is both allocated and initialized *)
-           Constructor.mk_store_stmt vi
-           :: Constructor.mk_initialize ~loc:Location.unknown (Cil.var vi)
+           Smart_stmt.store_stmt vi
+           :: Smart_stmt.initialize ~loc:Location.unknown (Cil.var vi)
            :: stmts)
       tbl
       stmts
@@ -136,10 +136,10 @@ let mk_init_function () =
          let loc = Location.unknown in
          let e = Cil.new_exp ~loc:loc (Const (CStr s)) in
          let str_size = Cil.new_exp loc (SizeOfStr s) in
-         Constructor.mk_assigns ~loc ~result:(Cil.var vi) e
-         :: Constructor.mk_store_stmt ~str_size vi
-         :: Constructor.mk_full_init_stmt vi
-         :: Constructor.mk_mark_readonly vi
+         Smart_stmt.assigns ~loc ~result:(Cil.var vi) e
+         :: Smart_stmt.store_stmt ~str_size vi
+         :: Smart_stmt.full_init_stmt vi
+         :: Smart_stmt.mark_readonly vi
          :: stmts)
       stmts
   in
@@ -150,7 +150,7 @@ let mk_init_function () =
       let b, _env = Env.pop_and_get env stmt ~global_clear:true Env.Before in
       b, stmts
   in
-  let stmts = Constructor.mk_block_stmt b :: stmts in
+  let stmts = Smart_stmt.block_stmt b :: stmts in
   (* prevent multiple calls to [__e_acsl_globals_init] *)
   let loc = Location.unknown in
   let vi_already_run =
@@ -168,14 +168,14 @@ let mk_init_function () =
       (Local_init (vi_already_run, init, loc))
   in
   let already_run =
-    Constructor.mk_assigns
+    Smart_stmt.assigns
       ~loc
       ~result:(Cil.var vi_already_run)
       (Cil.one ~loc)
   in
   let stmts = already_run :: stmts in
   let guard =
-    Constructor.mk_if
+    Smart_stmt.if_stmt
       ~loc
       ~cond:(Cil.evar vi_already_run)
       (Cil.mkBlock [])
@@ -195,7 +195,7 @@ let mk_delete_function () =
     Varinfo.Hashtbl.fold_sorted
       (fun vi _l acc ->
          if Misc.is_fc_or_compiler_builtin vi then acc
-         else Constructor.mk_delete_stmt vi :: acc)
+         else Smart_stmt.delete_stmt vi :: acc)
       tbl
       []
   in
diff --git a/src/plugins/e-acsl/src/code_generator/gmp.ml b/src/plugins/e-acsl/src/code_generator/gmp.ml
index 8c28ac5e32e0267754723bd1a0042f492fb6cb17..8a2b5385f1cb1830a92ff5272cb14bd0cd3d7c69 100644
--- a/src/plugins/e-acsl/src/code_generator/gmp.ml
+++ b/src/plugins/e-acsl/src/code_generator/gmp.ml
@@ -33,7 +33,7 @@ let apply_on_var ~loc funname e =
     else if Gmp_types.Q.is_t ty then "__gmpq_"
     else assert false
   in
-  Constructor.mk_lib_call ~loc (prefix ^ funname) [ e ]
+  Smart_stmt.lib_call ~loc (prefix ^ funname) [ e ]
 
 let init ~loc e = apply_on_var "init" ~loc e
 let clear ~loc e = apply_on_var "clear" ~loc e
@@ -90,9 +90,9 @@ let generic_affect ~loc fname lv ev e =
   let ty = Cil.typeOf ev in
   if Gmp_types.Z.is_t ty || Gmp_types.Q.is_t ty then begin
     let suf, args = get_set_suffix_and_arg ty e in
-    Constructor.mk_lib_call ~loc (fname ^ suf) (ev :: args)
+    Smart_stmt.lib_call ~loc (fname ^ suf) (ev :: args)
   end else
-    Constructor.mk_assigns ~loc:e.eloc ~result:lv e
+    Smart_stmt.assigns ~loc:e.eloc ~result:lv e
 
 let init_set ~loc lv ev e =
   let fname =
@@ -111,7 +111,7 @@ let init_set ~loc lv ev e =
      | Lval elv ->
        assert (Gmp_types.Z.is_t (Cil.typeOf ev));
        let call =
-         Constructor.mk_lib_call ~loc
+         Smart_stmt.lib_call ~loc
            "__gmpz_import"
            [ ev;
              Cil.one ~loc;
@@ -121,7 +121,7 @@ let init_set ~loc lv ev e =
              Cil.zero ~loc;
              Cil.mkAddrOf ~loc elv ]
        in
-       Constructor.mk_block_stmt (Cil.mkBlock [ init ~loc ev; call ])
+       Smart_stmt.block_stmt (Cil.mkBlock [ init ~loc ev; call ])
      | _ ->
        Error.not_yet "unsigned long long expression requiring GMP")
   | Longlong ILongLong ->
diff --git a/src/plugins/e-acsl/src/code_generator/injector.ml b/src/plugins/e-acsl/src/code_generator/injector.ml
index dd1222051d790f8757da083c9f9628ac3be4d877..cdc6486702d1fbcc234a0f0f7bf19b1f616e74c9 100644
--- a/src/plugins/e-acsl/src/code_generator/injector.ml
+++ b/src/plugins/e-acsl/src/code_generator/injector.ml
@@ -60,7 +60,7 @@ let inject_in_local_init loc env kf vi = function
   | ConsInit (fvi, sz :: _, _) as init
     when Functions.Libc.is_vla_alloc_name fvi.vname ->
     (* add a store statement when creating a variable length array *)
-    let store = Constructor.mk_store_stmt ~str_size:sz vi in
+    let store = Smart_stmt.store_stmt ~str_size:sz vi in
     let env = Env.add_stmt ~post:true env kf store in
     init, env
 
@@ -145,13 +145,13 @@ let add_initializer loc ?vi lv ?(post=false) stmt env kf =
         (* bitfields are not yet supported ==> no initializer.
            a [not_yet] will be raised in [Translate]. *)
         if Cil.isBitfield lv then Cil.mkEmptyStmt ()
-        else Constructor.mk_initialize ~loc lv
+        else Smart_stmt.initialize ~loc lv
       in
       let env = Env.add_stmt ~post ~before env kf new_stmt in
       let env = match vi with
         | None -> env
         | Some vi ->
-          let new_stmt = Constructor.mk_store_stmt vi in
+          let new_stmt = Smart_stmt.store_stmt vi in
           Env.add_stmt ~post ~before env kf new_stmt
       in
       env
@@ -189,7 +189,7 @@ let inject_in_instr env kf stmt = function
       if Functions.Libc.is_vla_free caller then
         match args with
         | [ { enode = CastE (_, { enode = Lval (Var vi, NoOffset) }) } ] ->
-          let delete_block = Constructor.mk_delete_stmt ~is_addr:true vi in
+          let delete_block = Smart_stmt.delete_stmt ~is_addr:true vi in
           Env.add_stmt env kf delete_block
         | _ -> Options.fatal "The normalization of __fc_vla_free() has changed"
       else
@@ -263,7 +263,7 @@ let add_new_block_in_stmt env kf stmt =
       let b, env =
         Env.pop_and_get env new_stmt ~global_clear:true Env.After
       in
-      let new_stmt = Constructor.mk_block stmt b in
+      let new_stmt = Smart_stmt.block stmt b in
       if not (Cil_datatype.Stmt.equal stmt new_stmt) then begin
         (* move the labels of the return to the new block in order to
            evaluate the postcondition when jumping to them. *)
@@ -293,7 +293,7 @@ let add_new_block_in_stmt env kf stmt =
       let post_block, env =
         Env.pop_and_get
           env
-          (Constructor.mk_block new_stmt pre_block)
+          (Smart_stmt.block new_stmt pre_block)
           ~global_clear:false
           Env.Before
       in
@@ -302,7 +302,7 @@ let add_new_block_in_stmt env kf stmt =
         then Cil.transient_block post_block
         else post_block
       in
-      let res = Constructor.mk_block new_stmt post_block in
+      let res = Smart_stmt.block new_stmt post_block in
       if not (Cil_datatype.Stmt.equal new_stmt res) then
         E_acsl_label.move kf new_stmt res;
       res, env
@@ -337,7 +337,7 @@ let insert_as_last_stmts_in_innermost_block ~last_stmts kf outer_block =
     match return_stmt with
     | Some return_stmt ->
       let b = Cil.mkBlock new_stmts in
-      let new_stmt = Constructor.mk_block return_stmt b in
+      let new_stmt = Smart_stmt.block return_stmt b in
       E_acsl_label.move kf return_stmt new_stmt;
       [ new_stmt ]
     | None -> new_stmts
@@ -516,7 +516,7 @@ and inject_in_block (env: Env.t) kf blk =
         List.fold_left
           (fun acc vi ->
              if Mmodel_analysis.must_model_vi ~kf vi
-             then Constructor.mk_delete_stmt vi :: acc
+             then Smart_stmt.delete_stmt vi :: acc
              else acc)
           stmts
           blk.blocals
@@ -531,7 +531,7 @@ and inject_in_block (env: Env.t) kf blk =
         List.fold_left
           (fun acc vi ->
              if Mmodel_analysis.must_model_vi vi && not vi.vdefined
-             then Constructor.mk_store_stmt vi :: acc
+             then Smart_stmt.store_stmt vi :: acc
              else acc)
           blk.bstmts
           blk.blocals;
@@ -821,8 +821,8 @@ let inject_mmodel_handler main =
       in
       let ptr_size = Cil.sizeOf loc Cil.voidPtrType in
       let args = args @ [ ptr_size ] in
-      let init = Constructor.mk_rtl_call loc "memory_init" args in
-      let clean = Constructor.mk_rtl_call loc "memory_clean" [] in
+      let init = Smart_stmt.rtl_call loc "memory_init" args in
+      let clean = Smart_stmt.rtl_call loc "memory_clean" [] in
       surround_function_with main fundec init (Some clean)
     in
     Extlib.may handle_main main
diff --git a/src/plugins/e-acsl/src/code_generator/logic_array.ml b/src/plugins/e-acsl/src/code_generator/logic_array.ml
index af522479dc6c22f7926c9edfee20c28821c1ce1a..08e9eda66c45e2f5e0967f4cd49c3a9340a85703 100644
--- a/src/plugins/e-acsl/src/code_generator/logic_array.ml
+++ b/src/plugins/e-acsl/src/code_generator/logic_array.ml
@@ -95,7 +95,7 @@ let length_exp ~loc kf env ~name array =
         ~name
         Cil.theMachine.typeOfSizeOf
         (fun v _ -> [
-             Constructor.mk_assigns
+             Smart_stmt.assigns
                ~loc
                ~result:(Cil.var v)
                (Cil.mkBinOp
@@ -168,7 +168,7 @@ let comparison_to_exp ~loc kf env ~name bop array1 array2 =
       None
       ~name
       Cil.intType
-      (fun v _ -> [ Constructor.mk_assigns ~loc ~result:(Cil.var v) (res_value ()) ])
+      (fun v _ -> [ Smart_stmt.assigns ~loc ~result:(Cil.var v) (res_value ()) ])
   in
 
   (* Retrieve the length of the arrays *)
@@ -193,8 +193,8 @@ let comparison_to_exp ~loc kf env ~name bop array1 array2 =
      arrays. This env will enable us to also check RTEs *)
   let env = Env.push env in
   (* Create the access to the arrays *)
-  let array1_iter_e = Constructor.mk_subscript ~loc array1 iter_e in
-  let array2_iter_e = Constructor.mk_subscript ~loc array2 iter_e in
+  let array1_iter_e = Smart_exp.subscript ~loc array1 iter_e in
+  let array2_iter_e = Smart_exp.subscript ~loc array2 iter_e in
   (* Check RTE on the arrays, filtering out bounding checks since the accesses
      are built already in bounds *)
   let filter a =
@@ -212,12 +212,12 @@ let comparison_to_exp ~loc kf env ~name bop array1 array2 =
   let cond = Cil.mkBinOp ~loc Ne array1_iter_e array2_iter_e in
   (* Create the statement representing the body of the for loop *)
   let body =
-    Constructor.mk_if
+    Smart_stmt.if_stmt
       ~loc
       ~cond
       (Cil.mkBlock [
-          Constructor.mk_assigns ~loc ~result:(Cil.var comparison_vi) (res_value ~flip:true ());
-          Constructor.mk_break ~loc
+          Smart_stmt.assigns ~loc ~result:(Cil.var comparison_vi) (res_value ~flip:true ());
+          Smart_stmt.break ~loc
         ])
   in
   (* Pop the env to build the body of the for loop *)
@@ -225,14 +225,14 @@ let comparison_to_exp ~loc kf env ~name bop array1 array2 =
 
   (* Create the statement representing the full for loop *)
   let for_loop =
-    (Constructor.mk_block_stmt
+    (Smart_stmt.block_stmt
        (Cil.mkBlock
           (Cil.mkForIncr
              ~iter
              ~first:(Cil.zero ~loc)
              ~stopat:len1_exp
              ~incr:(Cil.one ~loc)
-             ~body:[ Constructor.mk_block_stmt body_blk ]
+             ~body:[ Smart_stmt.block_stmt body_blk ]
           )
        )
     )
@@ -244,7 +244,7 @@ let comparison_to_exp ~loc kf env ~name bop array1 array2 =
 
   (* Add the check for the length before the for loop *)
   let prepend_coercion_check ~name env stmts array len =
-    let array_orig = Option.get (Constructor.extract_uncoerced_lval array) in
+    let array_orig = Option.get (Misc.extract_uncoerced_lval array) in
     if array_orig == array then
       stmts, env
     else
@@ -259,7 +259,7 @@ let comparison_to_exp ~loc kf env ~name bop array1 array2 =
       in
       let p = { p with pred_name = "array_coercion" :: p.pred_name } in
       let stmt =
-        Constructor.mk_runtime_check Constructor.RTE kf e p
+        Smart_stmt.runtime_check Smart_stmt.RTE kf e p
       in
       stmt :: stmts, env
   in
@@ -272,17 +272,17 @@ let comparison_to_exp ~loc kf env ~name bop array1 array2 =
 
   (* Pop the env to build the full then block *)
   let then_blk, env =
-    pop_and_get_env env (Constructor.mk_block_stmt (Cil.mkBlock then_stmts))
+    pop_and_get_env env (Smart_stmt.block_stmt (Cil.mkBlock then_stmts))
   in
 
   (* Create the statement representing the whole generated code *)
   let stmt =
-    Constructor.mk_if
+    Smart_stmt.if_stmt
       ~loc
       ~cond:(Cil.mkBinOp ~loc Eq len1_exp len2_exp)
       then_blk
       ~else_blk:(Cil.mkBlock
-                   [ Constructor.mk_assigns
+                   [ Smart_stmt.assigns
                        ~loc
                        ~result:(Cil.var comparison_vi)
                        (res_value ~flip:true ()) ])
diff --git a/src/plugins/e-acsl/src/code_generator/logic_functions.ml b/src/plugins/e-acsl/src/code_generator/logic_functions.ml
index d5bf1c4da99b052ef55ba976adb9eba5c4929ff7..97c6523575a25720e3316e1fd0a532bf7331894a 100644
--- a/src/plugins/e-acsl/src/code_generator/logic_functions.ml
+++ b/src/plugins/e-acsl/src/code_generator/logic_functions.ml
@@ -98,7 +98,7 @@ let term_to_block ~loc kf env ret_ty ret_vi t =
        function (by reference). *)
     let set =
       let lv_star_ret = Cil.mkMem ~addr:(Cil.evar ~loc ret_vi) ~off:NoOffset in
-      let star_ret = Constructor.mk_lval ~loc lv_star_ret in
+      let star_ret = Smart_exp.lval ~loc lv_star_ret in
       Gmp.init_set ~loc lv_star_ret star_ret e
     in
     let return_void = Cil.mkStmt ~valid_sid:true (Return (None, loc)) in
diff --git a/src/plugins/e-acsl/src/code_generator/loops.ml b/src/plugins/e-acsl/src/code_generator/loops.ml
index bca60ec4f2cd8197f440f38a15241dd03c70761e..c8a5f714ddc2b23fab8a20edded2bd7ea2b6d663 100644
--- a/src/plugins/e-acsl/src/code_generator/loops.ml
+++ b/src/plugins/e-acsl/src/code_generator/loops.ml
@@ -59,11 +59,11 @@ let preserve_invariant env kf stmt = match stmt.skind with
         let blk, env =
           Env.pop_and_get env last ~global_clear:false Env.Before
         in
-        Constructor.mk_block last blk :: stmts, env
+        Smart_stmt.block last blk :: stmts, env
       | s :: tl ->
         handle_invariants (s :: stmts, env) tl
     in
-    let env = Env.set_annotation_kind env Constructor.Invariant in
+    let env = Env.set_annotation_kind env Smart_stmt.Invariant in
     let stmts, env = handle_invariants ([], env) stmts in
     let new_blk = { blk with bstmts = List.rev stmts } in
     { stmt with skind = Loop([], new_blk, loc, cont, break) },
@@ -212,7 +212,7 @@ let rec mk_nested_loops ~loc mk_innermost_block kf env lscope_vars =
         Env.Middle
     in
     (* generate the guard [x bop t2] *)
-    let block_to_stmt b = Constructor.mk_block_stmt b in
+    let block_to_stmt b = Smart_stmt.block_stmt b in
     let tlv = Logic_const.tvar ~loc logic_x in
     let guard =
       (* must copy [t2] to force being typed again *)
@@ -221,10 +221,10 @@ let rec mk_nested_loops ~loc mk_innermost_block kf env lscope_vars =
     in
     Typing.type_term ~use_gmp_opt:false ~ctx:Typing.c_int guard;
     let guard_exp, env = term_to_exp kf (Env.push env) guard in
-    let break_stmt = Constructor.mk_break ~loc:guard_exp.eloc in
+    let break_stmt = Smart_stmt.break ~loc:guard_exp.eloc in
     let guard_blk, env = Env.pop_and_get
         env
-        (Constructor.mk_if
+        (Smart_stmt.if_stmt
            ~loc:guard_exp.eloc
            ~cond:guard_exp
            (mkBlock [ mkEmptyStmt ~loc () ])
@@ -251,10 +251,10 @@ let rec mk_nested_loops ~loc mk_innermost_block kf env lscope_vars =
       | Some p ->
         let e, env = !named_predicate_ref kf (Env.push env) p in
         let stmt, env =
-          Constructor.mk_runtime_check Constructor.RTE kf e p, env
+          Smart_stmt.runtime_check Smart_stmt.RTE kf e p, env
         in
         let b, env = Env.pop_and_get env stmt ~global_clear:false Env.After in
-        let guard_for_small_type = Constructor.mk_block_stmt b in
+        let guard_for_small_type = Smart_stmt.block_stmt b in
         guard_for_small_type :: guard :: body @ [ next ], env
     in
     let start = block_to_stmt init_blk in
diff --git a/src/plugins/e-acsl/src/code_generator/memory_observer.ml b/src/plugins/e-acsl/src/code_generator/memory_observer.ml
index 0ec5cda04ef5f39be1210766ebaca866b748dd37..629e30432278b7a6912f33453939a7476c31632e 100644
--- a/src/plugins/e-acsl/src/code_generator/memory_observer.ml
+++ b/src/plugins/e-acsl/src/code_generator/memory_observer.ml
@@ -39,7 +39,7 @@ let store ?before env kf vars =
   tracking_stmt
     ?before
     List.fold_right (* small list *)
-    Constructor.mk_store_stmt
+    Smart_stmt.store_stmt
     env
     kf
     vars
@@ -48,7 +48,7 @@ let duplicate_store ?before env kf vars =
   tracking_stmt
     ?before
     Varinfo.Set.fold
-    Constructor.mk_duplicate_store_stmt
+    Smart_stmt.duplicate_store_stmt
     env
     kf
     vars
@@ -57,7 +57,7 @@ let delete_from_list ?before env kf vars =
   tracking_stmt
     ?before
     List.fold_right (* small list *)
-    Constructor.mk_delete_stmt
+    Smart_stmt.delete_stmt
     env
     kf
     vars
@@ -66,7 +66,7 @@ let delete_from_set ?before env kf vars =
   tracking_stmt
     ?before
     Varinfo.Set.fold
-    Constructor.mk_delete_stmt
+    Smart_stmt.delete_stmt
     env
     kf
     vars
diff --git a/src/plugins/e-acsl/src/code_generator/mmodel_translate.ml b/src/plugins/e-acsl/src/code_generator/mmodel_translate.ml
index f5cae16eb0bdb82fc8330038a5c218c6c79f50f7..654433624a3147fc868f052b6d16ab13c9adfaa1 100644
--- a/src/plugins/e-acsl/src/code_generator/mmodel_translate.ml
+++ b/src/plugins/e-acsl/src/code_generator/mmodel_translate.ml
@@ -155,8 +155,8 @@ let gmp_to_sizet ~loc kf env size p =
       None
       sizet
       (fun vi _ ->
-         [ Constructor.mk_runtime_check Constructor.RTE kf guard p;
-           Constructor.mk_lib_call ~loc
+         [ Smart_stmt.runtime_check Smart_stmt.RTE kf guard p;
+           Smart_stmt.lib_call ~loc
              ~result:(Cil.var vi)
              "__gmpz_get_ui"
              [ size ] ])
diff --git a/src/plugins/e-acsl/src/code_generator/quantif.ml b/src/plugins/e-acsl/src/code_generator/quantif.ml
index b6114f25cd132102a8ccd4e606ca1ad303c2047a..b32d939f05d87cf39e1b798480a59e53a44b6d52 100644
--- a/src/plugins/e-acsl/src/code_generator/quantif.ml
+++ b/src/plugins/e-acsl/src/code_generator/quantif.ml
@@ -174,7 +174,7 @@ let convert kf env loc is_forall p bounded_vars hyps goal =
           intType
           (fun v _ ->
              let lv = var v in
-             [ Constructor.mk_assigns ~loc ~result:lv init_val ])
+             [ Smart_stmt.assigns ~loc ~result:lv init_val ])
       in
       let end_loop_ref = ref dummyStmt in
       (* innermost block *)
@@ -188,23 +188,23 @@ let convert kf env loc is_forall p bounded_vars hyps goal =
           (* use a 'goto', not a simple 'break' in order to handle 'forall' with
              multiple binders (leading to imbricated loops) *)
           mkBlock
-            [ Constructor.mk_assigns ~loc ~result:(var var_res) found_val;
+            [ Smart_stmt.assigns ~loc ~result:(var var_res) found_val;
               mkStmt ~valid_sid:true (Goto(end_loop_ref, loc)) ]
         in
         let blk, env = Env.pop_and_get
             env
-            (Constructor.mk_if ~loc ~cond:(mk_guard test) then_blk ~else_blk)
+            (Smart_stmt.if_stmt ~loc ~cond:(mk_guard test) then_blk ~else_blk)
             ~global_clear:false
             Env.After
         in
         let blk = Cil.flatten_transient_sub_blocks blk in
-        [ Constructor.mk_block_stmt blk ], env
+        [ Smart_stmt.block_stmt blk ], env
       in
       let stmts, env =
         Loops.mk_nested_loops ~loc mk_innermost_block kf env lvs_guards
       in
       let env =
-        Env.add_stmt env kf (Constructor.mk_block_stmt (mkBlock stmts))
+        Env.add_stmt env kf (Smart_stmt.block_stmt (mkBlock stmts))
       in
       (* where to jump to go out of the loop *)
       let end_loop = mkEmptyStmt ~loc () in
diff --git a/src/plugins/e-acsl/src/code_generator/rational.ml b/src/plugins/e-acsl/src/code_generator/rational.ml
index 3a0da53951b3b4f569e7f55bc2ea3d4849e1fcc4..2f4417b0191213b6730879074147a5f66f68fe43 100644
--- a/src/plugins/e-acsl/src/code_generator/rational.ml
+++ b/src/plugins/e-acsl/src/code_generator/rational.ml
@@ -24,7 +24,7 @@ open Cil_types
 
 (* No init_set for GMPQ: init then set separately *)
 let init_set ~loc lval vi_e e =
-  Constructor.mk_block_stmt
+  Smart_stmt.block_stmt
     (Cil.mkBlock
        [ Gmp.init ~loc vi_e ;
          Gmp.affect ~loc lval vi_e e ])
@@ -148,7 +148,7 @@ let add_cast ~loc ?name e env kf ty =
         None
         Cil.doubleType
         (fun v _ ->
-           [ Constructor.mk_lib_call ~loc
+           [ Smart_stmt.lib_call ~loc
                ~result:(Cil.var v)
                "__gmpq_get_d"
                [ e ] ])
@@ -197,7 +197,7 @@ let cmp ~loc bop e1 e2 env kf t_opt =
       ~name
       Cil.intType
       (fun v _ ->
-         [ Constructor.mk_lib_call ~loc ~result:(Cil.var v) fname [ e1; e2 ] ])
+         [ Smart_stmt.lib_call ~loc ~result:(Cil.var v) fname [ e1; e2 ] ])
   in
   Cil.new_exp ~loc (BinOp(bop, e, Cil.zero ~loc, Cil.intType)), env
 
@@ -226,7 +226,7 @@ let binop ~loc bop e1 e2 env kf t_opt =
      [e2] *)
   let e1, env = create ~loc e1 env kf None in
   let e2, env = create ~loc e2 env kf None in
-  let mk_stmts _ e = [ Constructor.mk_lib_call ~loc name [ e; e1; e2 ] ] in
+  let mk_stmts _ e = [ Smart_stmt.lib_call ~loc name [ e; e1; e2 ] ] in
   let name = Misc.name_of_binop bop in
   let _, e, env = new_var_and_init ~loc ~name env kf t_opt mk_stmts in
   e, env
diff --git a/src/plugins/e-acsl/src/code_generator/smart_exp.ml b/src/plugins/e-acsl/src/code_generator/smart_exp.ml
new file mode 100644
index 0000000000000000000000000000000000000000..f3dac85ffd20bd197d046e874ae3a7a40f68e207
--- /dev/null
+++ b/src/plugins/e-acsl/src/code_generator/smart_exp.ml
@@ -0,0 +1,46 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of the Frama-C's E-ACSL plug-in.                    *)
+(*                                                                        *)
+(*  Copyright (C) 2012-2020                                               *)
+(*    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
+
+let lval ~loc lv =
+  Cil.new_exp ~loc (Lval lv)
+
+let deref ~loc lv = lval ~loc (Mem lv, NoOffset)
+
+let subscript ~loc array idx =
+  match Misc.extract_uncoerced_lval array with
+  | Some { enode = Lval lv } ->
+    let subscript_lval = Cil.addOffsetLval (Index(idx, NoOffset)) lv in
+    lval ~loc subscript_lval
+  | Some _ | None ->
+    Options.fatal
+      ~current:true
+      "Trying to create a subscript on an array that is not an Lval: %a"
+      Cil_types_debug.pp_exp
+      array
+
+(*
+Local Variables:
+compile-command: "make -C ../../../../.."
+End:
+*)
diff --git a/src/plugins/e-acsl/src/code_generator/smart_exp.mli b/src/plugins/e-acsl/src/code_generator/smart_exp.mli
new file mode 100644
index 0000000000000000000000000000000000000000..566702f1e8012f361cfb3beaf9e3683bf50f94a4
--- /dev/null
+++ b/src/plugins/e-acsl/src/code_generator/smart_exp.mli
@@ -0,0 +1,43 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of the Frama-C's E-ACSL plug-in.                    *)
+(*                                                                        *)
+(*  Copyright (C) 2012-2020                                               *)
+(*    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
+
+(* ********************************************************************** *)
+(* Helper functions to build expressions *)
+(* ********************************************************************** *)
+
+val lval: loc:location -> lval -> exp
+(** Construct an lval expression from an lval. *)
+
+val deref: loc:location -> exp -> exp
+(** Construct a dereference of an expression. *)
+
+val subscript: loc:location -> exp -> exp -> exp
+(** [mk_subscript ~loc array idx] Create an expression to access the [idx]'th
+    element of the [array]. *)
+
+(*
+Local Variables:
+compile-command: "make -C ../../../../.."
+End:
+*)
diff --git a/src/plugins/e-acsl/src/code_generator/constructor.ml b/src/plugins/e-acsl/src/code_generator/smart_stmt.ml
similarity index 70%
rename from src/plugins/e-acsl/src/code_generator/constructor.ml
rename to src/plugins/e-acsl/src/code_generator/smart_stmt.ml
index a38f36ce70e425255853780dbbf358bef43cc0ab..dec6438762f3afb494812fa1799af9bb3557ebc6 100644
--- a/src/plugins/e-acsl/src/code_generator/constructor.ml
+++ b/src/plugins/e-acsl/src/code_generator/smart_stmt.ml
@@ -22,51 +22,21 @@
 
 open Cil_types
 
-(* ********************************************************************** *)
-(* Expressions *)
-(* ********************************************************************** *)
-
-let extract_uncoerced_lval e =
-  let rec aux e =
-    match e.enode with
-    | Lval _ -> Some e
-    | CastE (_, e) -> aux e
-    | _ -> None
-  in
-  aux e
-
-let mk_lval ~loc lval =
-  Cil.new_exp ~loc (Lval lval)
-
-let mk_deref ~loc lv = mk_lval ~loc (Mem lv, NoOffset)
-
-let mk_subscript ~loc array idx =
-  match extract_uncoerced_lval array with
-  | Some { enode = Lval lval } ->
-    let subscript_lval = Cil.addOffsetLval (Index(idx, NoOffset)) lval in
-    mk_lval ~loc subscript_lval
-  | Some _ | None ->
-    Options.fatal
-      ~current:true
-      "Trying to create a subscript on an array that is not an Lval: %a"
-      Cil_types_debug.pp_exp
-      array
-
 (* ********************************************************************** *)
 (* Statements *)
 (* ********************************************************************** *)
 
-let mk_stmt sk = Cil.mkStmt ~valid_sid:true sk
-let mk_instr i = mk_stmt (Instr i)
-let mk_block_stmt blk = mk_stmt (Block blk)
-let mk_call ~loc ?result e args = mk_instr (Call(result, e, args, loc))
+let stmt sk = Cil.mkStmt ~valid_sid:true sk
+let instr i = stmt (Instr i)
+let block_stmt blk = stmt (Block blk)
+let call ~loc ?result e args = instr (Call(result, e, args, loc))
 
-let mk_assigns ~loc ~result e = mk_instr (Set(result, e, loc))
+let assigns ~loc ~result e = instr (Set(result, e, loc))
 
-let mk_if ~loc ~cond ?(else_blk=Cil.mkBlock []) then_blk =
-  mk_stmt (If (cond, then_blk, else_blk, loc))
+let if_stmt ~loc ~cond ?(else_blk=Cil.mkBlock []) then_blk =
+  stmt (If (cond, then_blk, else_blk, loc))
 
-let mk_break ~loc = mk_stmt (Break loc)
+let break ~loc = stmt (Break loc)
 
 type annotation_kind =
   | Assertion
@@ -85,19 +55,19 @@ let kind_to_string loc k =
      | Invariant -> "Invariant"
      | RTE -> "RTE")
 
-let mk_block stmt b = match b.bstmts with
+let block stmt b = match b.bstmts with
   | [] ->
     (match stmt.skind with
      | Instr(Skip _) -> stmt
      | _ -> assert false)
   | [ s ] -> s
-  |  _ :: _ -> mk_block_stmt b
+  |  _ :: _ -> block_stmt b
 
 (* ********************************************************************** *)
 (* E-ACSL specific code *)
 (* ********************************************************************** *)
 
-let mk_lib_call ~loc ?result fname args =
+let lib_call ~loc ?result fname args =
   let vi =
     try Rtl.Symbols.find_vi fname
     with Rtl.Symbols.Unregistered _ as exn ->
@@ -133,32 +103,32 @@ let mk_lib_call ~loc ?result fname args =
     | TFun(_, None, _, _) -> []
     | _ -> assert false
   in
-  mk_call ~loc ?result f args
+  call ~loc ?result f args
 
-let mk_rtl_call ~loc ?result fname args =
-  mk_lib_call ~loc ?result (Functions.RTL.mk_api_name fname) args
+let rtl_call ~loc ?result fname args =
+  lib_call ~loc ?result (Functions.RTL.mk_api_name fname) args
 
 (* ************************************************************************** *)
 (** {2 Handling the E-ACSL's C-libraries, part II} *)
 (* ************************************************************************** *)
 
-let mk_full_init_stmt vi =
+let full_init_stmt vi =
   let loc = vi.vdecl in
-  mk_rtl_call ~loc "full_init" [ Cil.evar ~loc vi ]
+  rtl_call ~loc "full_init" [ Cil.evar ~loc vi ]
 
-let mk_initialize ~loc (host, offset as lv) = match host, offset with
+let initialize ~loc (host, offset as lv) = match host, offset with
   | Var _, NoOffset ->
-    mk_rtl_call ~loc "full_init" [ Cil.mkAddrOf ~loc lv ]
+    rtl_call ~loc "full_init" [ Cil.mkAddrOf ~loc lv ]
   | _ ->
     let typ = Cil.typeOfLval lv in
-    mk_rtl_call ~loc
+    rtl_call ~loc
       "initialize"
       [ Cil.mkAddrOf ~loc lv; Cil.new_exp loc (SizeOf typ) ]
 
-let mk_named_store_stmt name ?str_size vi =
+let named_store_stmt name ?str_size vi =
   let ty = Cil.unrollType vi.vtype in
   let loc = vi.vdecl in
-  let store = mk_rtl_call ~loc name in
+  let store = rtl_call ~loc name in
   match ty, str_size with
   | TArray(_, Some _,_,_), None ->
     store [ Cil.evar ~loc vi; Cil.sizeOf ~loc ty ]
@@ -178,27 +148,27 @@ let mk_named_store_stmt name ?str_size vi =
       Printer.pp_typ ty
       Printer.pp_exp size
 
-let mk_store_stmt ?str_size vi =
-  mk_named_store_stmt "store_block" ?str_size vi
+let store_stmt ?str_size vi =
+  named_store_stmt "store_block" ?str_size vi
 
-let mk_duplicate_store_stmt ?str_size vi =
-  mk_named_store_stmt "store_block_duplicate" ?str_size vi
+let duplicate_store_stmt ?str_size vi =
+  named_store_stmt "store_block_duplicate" ?str_size vi
 
-let mk_delete_stmt ?(is_addr=false) vi =
+let delete_stmt ?(is_addr=false) vi =
   let loc = vi.vdecl in
-  let mk = mk_rtl_call ~loc "delete_block" in
+  let mk = rtl_call ~loc "delete_block" in
   match is_addr, Cil.unrollType vi.vtype with
   | _, TArray(_, Some _, _, _) | true, _ -> mk [ Cil.evar ~loc vi ]
   | _ -> mk [ Cil.mkAddrOfVi vi ]
 
-let mk_mark_readonly vi =
+let mark_readonly vi =
   let loc = vi.vdecl in
-  mk_rtl_call ~loc "mark_readonly" [ Cil.evar ~loc vi ]
+  rtl_call ~loc "mark_readonly" [ Cil.evar ~loc vi ]
 
-let mk_runtime_check_with_msg ~loc msg kind kf e =
+let runtime_check_with_msg ~loc msg kind kf e =
   let file = (fst loc).Filepath.pos_path in
   let line = (fst loc).Filepath.pos_lnum in
-  mk_rtl_call ~loc
+  rtl_call ~loc
     "assert"
     [ e;
       kind_to_string loc kind;
@@ -207,13 +177,13 @@ let mk_runtime_check_with_msg ~loc msg kind kf e =
       Cil.mkString ~loc (Filepath.Normalized.to_pretty_string file);
       Cil.integer loc line ]
 
-let mk_runtime_check kind kf e p =
+let runtime_check kind kf e p =
   let loc = p.pred_loc in
   let msg =
     Kernel.Unicode.without_unicode
       (Format.asprintf "%a@?" Printer.pp_predicate) p
   in
-  mk_runtime_check_with_msg ~loc msg kind kf e
+  runtime_check_with_msg ~loc msg kind kf e
 
 (*
 Local Variables:
diff --git a/src/plugins/e-acsl/src/code_generator/constructor.mli b/src/plugins/e-acsl/src/code_generator/smart_stmt.mli
similarity index 64%
rename from src/plugins/e-acsl/src/code_generator/constructor.mli
rename to src/plugins/e-acsl/src/code_generator/smart_stmt.mli
index d21c71e53a434f9905a89fc1ca49ab31df10a781..e0c919a7f8847b7c23e71d536b619837ed59a2f5 100644
--- a/src/plugins/e-acsl/src/code_generator/constructor.mli
+++ b/src/plugins/e-acsl/src/code_generator/smart_stmt.mli
@@ -20,97 +20,73 @@
 (*                                                                        *)
 (**************************************************************************)
 
-(** Smart constructors for building C code. *)
-
 open Cil_types
-open Cil_datatype
-
-(* ********************************************************************** *)
-(* Expressions *)
-(* ********************************************************************** *)
-
-val extract_uncoerced_lval: exp -> exp option
-(** Unroll the [CastE] part of the expression until an [Lval] is found, and
-    return it.
-
-    If at some point the expression is neither a [CastE] nor an [Lval], then
-    return [None]. *)
-
-val mk_lval: loc:location -> lval -> exp
-(** Construct an lval expression from an lval. *)
-
-val mk_deref: loc:Location.t -> exp -> exp
-(** Construct a dereference of an expression. *)
-
-val mk_subscript: loc:location -> exp -> exp -> exp
-(** [mk_subscript ~loc array idx] Create an expression to access the [idx]'th
-    element of the [array]. *)
 
 (* ********************************************************************** *)
-(* Statements *)
+(* Helper functions to build statements *)
 (* ********************************************************************** *)
 
-val mk_stmt: stmtkind -> stmt
+val stmt: stmtkind -> stmt
 (** Create a statement from a statement kind. *)
 
-val mk_block: stmt -> block -> stmt
+val block: stmt -> block -> stmt
 (** Create a block statement from a block to replace a given statement.
     Requires that (1) the block is not empty, or (2) the statement is a skip. *)
 
-val mk_block_stmt: block -> stmt
+val block_stmt: block -> stmt
 (** Create a block statement from a block *)
 
-val mk_assigns: loc:location -> result:lval -> exp -> stmt
-(** [mk_assigns ~loc ~result value] create a statement to assign the [value]
+val assigns: loc:location -> result:lval -> exp -> stmt
+(** [assigns ~loc ~result value] create a statement to assign the [value]
     expression to the [result] lval. *)
 
-val mk_if:
+val if_stmt:
   loc:location -> cond:exp -> ?else_blk:block -> block -> stmt
-(** [mk_if ~loc ~cond ~then_blk ~else_blk] create an if statement with [cond]
+(** [if ~loc ~cond ~then_blk ~else_blk] create an if statement with [cond]
     as condition and [then_blk] and [else_blk] as respectively "then" block and
     "else" block. *)
 
-val mk_break: loc:location -> stmt
+val break: loc:location -> stmt
 (** Create a break statement *)
 
 (* ********************************************************************** *)
 (* E-ACSL specific code: build calls to its RTL API *)
 (* ********************************************************************** *)
 
-val mk_lib_call: loc:Location.t -> ?result:lval -> string -> exp list -> stmt
+val lib_call: loc:location -> ?result:lval -> string -> exp list -> stmt
 (** Construct a call to a library function with the given name.
     @raise Rtl.Symbols.Unregistered if the given string does not represent
     such a function or if library functions were never registered (only possible
     when using E-ACSL through its API). *)
 
-val mk_rtl_call: loc:Location.t -> ?result:lval -> string -> exp list -> stmt
-(** Special version of [mk_lib_call] for E-ACSL's RTL functions. *)
+val rtl_call: loc:location -> ?result:lval -> string -> exp list -> stmt
+(** Special version of [lib_call] for E-ACSL's RTL functions. *)
 
-val mk_store_stmt: ?str_size:exp -> varinfo -> stmt
+val store_stmt: ?str_size:exp -> varinfo -> stmt
 (** Construct a call to [__e_acsl_store_block] that observes the allocation of
     the given varinfo. See [share/e-acsl/e_acsl.h] for details about this
     function. *)
 
-val mk_duplicate_store_stmt: ?str_size:exp -> varinfo -> stmt
-(** Same as [mk_store_stmt] for [__e_acsl_duplicate_store_block] that first
+val duplicate_store_stmt: ?str_size:exp -> varinfo -> stmt
+(** Same as [store_stmt] for [__e_acsl_duplicate_store_block] that first
     checks for a previous allocation of the given varinfo. *)
 
-val mk_delete_stmt: ?is_addr:bool -> varinfo -> stmt
-(** Same as [mk_store_stmt] for [__e_acsl_delete_block] that observes the
+val delete_stmt: ?is_addr:bool -> varinfo -> stmt
+(** Same as [store_stmt] for [__e_acsl_delete_block] that observes the
     de-allocation of the given varinfo.
     If [is_addr] is false (default), take the address of varinfo. *)
 
-val mk_full_init_stmt: varinfo -> stmt
-(** Same as [mk_store_stmt] for [__e_acsl_full_init] that observes the
+val full_init_stmt: varinfo -> stmt
+(** Same as [store_stmt] for [__e_acsl_full_init] that observes the
     initialization of the given varinfo. The varinfo is the address to fully
     initialize, no [addrOf] is taken. *)
 
-val mk_initialize: loc:location -> lval -> stmt
-(** Same as [mk_store_stmt] for [__e_acsl_initialize] that observes the
+val initialize: loc:location -> lval -> stmt
+(** Same as [store_stmt] for [__e_acsl_initialize] that observes the
     initialization of the given left-value. *)
 
-val mk_mark_readonly: varinfo -> stmt
-(** Same as [mk_store_stmt] for [__e_acsl_markreadonly] that observes the
+val mark_readonly: varinfo -> stmt
+(** Same as [store_stmt] for [__e_acsl_markreadonly] that observes the
     read-onlyness of the given varinfo. *)
 
 type annotation_kind =
@@ -120,16 +96,16 @@ type annotation_kind =
   | Invariant
   | RTE
 
-val mk_runtime_check:
+val runtime_check:
   annotation_kind -> kernel_function -> exp -> predicate -> stmt
-(** [mk_runtime_check kind kf e p] generates a runtime check for predicate [p]
+(** [runtime_check kind kf e p] generates a runtime check for predicate [p]
     by building a call to [__e_acsl_assert]. [e] (or [!e] if [reverse] is set to
     [true]) is the C translation of [p], [kf] is the current kernel_function and
     [kind] is the annotation kind of [p]. *)
 
-val mk_runtime_check_with_msg:
+val runtime_check_with_msg:
   loc:location -> string -> annotation_kind -> kernel_function -> exp -> stmt
-(** [mk_runtime_check_with_msg kind kf e msg] generates a runtime check for [e]
+(** [runtime_check_with_msg kind kf e msg] generates a runtime check for [e]
     (or [!e] if [reverse] is [true]) by building a call to [__e_acsl_assert].
     [msg] is the message printed if the runtime check fails. [loc] is the
     location printed in the message if the runtime check fails. [kf] is the
diff --git a/src/plugins/e-acsl/src/code_generator/temporal.ml b/src/plugins/e-acsl/src/code_generator/temporal.ml
index a2694969cc618f039f6314f651099618e8985184..96f5c22ee29764fd99bded8ea64abf265fabb0d0 100644
--- a/src/plugins/e-acsl/src/code_generator/temporal.ml
+++ b/src/plugins/e-acsl/src/code_generator/temporal.ml
@@ -51,9 +51,9 @@ type flow =
 
 module Mk: sig
   (* Generate either
-      - [store_nblock(lhs, rhs)], or
-      - [store_nreferent(lhs, rhs)]
-     function call based on the value of [flow] *)
+     - [store_nblock(lhs, rhs)], or
+     - [store_nreferent(lhs, rhs)]
+       function call based on the value of [flow] *)
   val store_reference: loc:location -> flow -> lval -> exp -> stmt
 
   (* Generate a [save_*_parameter] call *)
@@ -81,7 +81,7 @@ end = struct
       | Copy -> Options.fatal "Copy flow type in store_reference"
     in
     let fname = RTL.mk_temporal_name fname in
-    Constructor.mk_lib_call ~loc fname [ Cil.mkAddrOf ~loc lhs; rhs ]
+    Smart_stmt.lib_call ~loc fname [ Cil.mkAddrOf ~loc lhs; rhs ]
 
   let save_param ~loc flow lhs pos =
     let infix = match flow with
@@ -91,13 +91,13 @@ end = struct
     in
     let fname = "save_" ^ infix ^ "_parameter" in
     let fname = RTL.mk_temporal_name fname in
-    Constructor.mk_lib_call ~loc fname [ lhs ; Cil.integer ~loc pos ]
+    Smart_stmt.lib_call ~loc fname [ lhs ; Cil.integer ~loc pos ]
 
   let pull_param ~loc vi pos =
     let exp = Cil.mkAddrOfVi vi in
     let fname = RTL.mk_temporal_name "pull_parameter" in
     let sz = Cil.kinteger ~loc IULong (Cil.bytesSizeOf vi.vtype) in
-    Constructor.mk_lib_call ~loc fname [ exp ; Cil.integer ~loc pos ; sz ]
+    Smart_stmt.lib_call ~loc fname [ exp ; Cil.integer ~loc pos ; sz ]
 
   let handle_return_referent ~save ~loc lhs =
     let fname = match save with
@@ -106,17 +106,17 @@ end = struct
     in
     (* TODO: Returning structs is unsupported so far *)
     (match (Cil.typeOf lhs) with
-      | TPtr _ -> ()
-      | _ -> Error.not_yet "Struct in return");
-    Constructor.mk_lib_call ~loc (RTL.mk_temporal_name fname) [ lhs ]
+     | TPtr _ -> ()
+     | _ -> Error.not_yet "Struct in return");
+    Smart_stmt.lib_call ~loc (RTL.mk_temporal_name fname) [ lhs ]
 
   let reset_return_referent ~loc =
-    Constructor.mk_lib_call ~loc (RTL.mk_temporal_name "reset_return") []
+    Smart_stmt.lib_call ~loc (RTL.mk_temporal_name "reset_return") []
 
   let temporal_memcpy_struct ~loc lhs rhs =
     let fname  = RTL.mk_temporal_name "memcpy" in
     let size = Cil.sizeOf ~loc (Cil.typeOfLval lhs) in
-    Constructor.mk_lib_call ~loc fname [ Cil.mkAddrOf ~loc lhs; rhs; size ]
+    Smart_stmt.lib_call ~loc fname [ Cil.mkAddrOf ~loc lhs; rhs; size ]
 end
 (* }}} *)
 
@@ -125,10 +125,10 @@ end
 (* ************************************************************************** *)
 
 (* Given an lvalue [lhs] representing LHS of an assignment, and an expression
-  [rhs] representing its RHS compute triple (l,r,f), such that:
+   [rhs] representing its RHS compute triple (l,r,f), such that:
    - lval [l] and exp [r] are addresses of a pointer and a memory block, and
    - flow [f] indicates how to update the meta-data of [l] using information
-    stored by [r]. The values of [f] indicate the following
+     stored by [r]. The values of [f] indicate the following
      + Direct - referent number of [l] is assigned the referent number of [r]
      + Indirect - referent number of [l] is assigned the origin number of [r]
      + Copy - metadata of [r] is copied to metadata of [l] *)
@@ -145,51 +145,52 @@ let assign ?(ltype) lhs rhs loc =
     let base, _ = Misc.ptr_index rhs in
     let rhs, flow =
       (match base.enode with
-      | AddrOf _
-      | StartOf _ -> rhs, Direct
-      (* Unary operator describes !, ~ or -: treat it same as Const since
-         it implies integer or logical operations. This case is rare but
-         happens: for instance in Gap SPEC CPU benchmark the returned pointer
-         is assigned -1 (for whatever bizarre reason) *)
-      | Const _ | UnOp _ -> base, Direct
-      (* Special case for literal strings which E-ACSL rewrites into
-         global variables: take the origin number of a string *)
-      | Lval(Var vi, _) when RTL.is_generated_name vi.vname ->
-        base, Direct
-      (* Lvalue of a pointer type can be a cast of an integral type, for
-         instance for the case when address is taken by value (shown via the
-         following example).
-           uintptr_t addr = ...;
-           char *p = (char* )addr;
-         If this is the case then the analysis takes the value of a variable. *)
-      | Lval lv ->
-        if Cil.isPointerType (Cil.unrollType (Cil.typeOfLval lv)) then
-          Cil.mkAddrOf ~loc lv, Indirect
-        else
-          rhs, Direct
-      (* Binary operation which yields an integer (or FP) type.
-         Since LHS is of pointer type we assume that the whole integer
-         expression computes to an address for which there is no
-         outer container, so the only thing to do is to take origin number *)
-      | BinOp(op, _, _, _) ->
-        (* At this point [ptr_index] should have split pointer arithmetic into
-           base pointer and index so there should be no pointer arithmetic
-           operations there. The following bit is to make sure of it. *)
-        (match op with
+       | AddrOf _
+       | StartOf _ -> rhs, Direct
+       (* Unary operator describes !, ~ or -: treat it same as Const since
+          it implies integer or logical operations. This case is rare but
+          happens: for instance in Gap SPEC CPU benchmark the returned pointer
+          is assigned -1 (for whatever bizarre reason) *)
+       | Const _ | UnOp _ -> base, Direct
+       (* Special case for literal strings which E-ACSL rewrites into
+          global variables: take the origin number of a string *)
+       | Lval(Var vi, _) when RTL.is_generated_name vi.vname ->
+         base, Direct
+       (* Lvalue of a pointer type can be a cast of an integral type, for
+          instance for the case when address is taken by value (shown via the
+          following example).
+            uintptr_t addr = ...;
+            char *p = (char* )addr;
+          If this is the case then the analysis takes the value of a variable.
+       *)
+       | Lval lv ->
+         if Cil.isPointerType (Cil.unrollType (Cil.typeOfLval lv)) then
+           Cil.mkAddrOf ~loc lv, Indirect
+         else
+           rhs, Direct
+       (* Binary operation which yields an integer (or FP) type.
+          Since LHS is of pointer type we assume that the whole integer
+          expression computes to an address for which there is no
+          outer container, so the only thing to do is to take origin number *)
+       | BinOp(op, _, _, _) ->
+         (* At this point [ptr_index] should have split pointer arithmetic into
+            base pointer and index so there should be no pointer arithmetic
+            operations there. The following bit is to make sure of it. *)
+         (match op with
           | MinusPI | PlusPI | IndexPI -> assert false
           | _ -> ());
-        base, Direct
-      | _ -> assert false)
+         base, Direct
+       | _ -> assert false)
     in Some (lhs, rhs, flow)
   | TNamed _ -> assert false
   | TInt _ | TFloat _ | TEnum _ -> None
   | TComp _ ->
     let rhs = match rhs.enode with
-    | AddrOf _ -> rhs
-    | Lval lv -> Cil.mkAddrOf ~loc lv
-    | Const _ | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _ | AlignOfE _
-    | UnOp _ | BinOp _ | CastE _ | StartOf _ | Info _ ->
-      Options.abort "unsupported RHS %a" Printer.pp_exp rhs
+      | AddrOf _ -> rhs
+      | Lval lv -> Cil.mkAddrOf ~loc lv
+      | Const _ | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _ | AlignOfE _
+      | UnOp _ | BinOp _ | CastE _ | StartOf _ | Info _ ->
+        Options.abort "unsupported RHS %a" Printer.pp_exp rhs
     in Some (lhs, rhs, Copy)
   (* va_list is a builtin type, we assume it has no pointers here and treat
      it as a "big" integer rather than a struct *)
@@ -240,29 +241,29 @@ end = struct
      structure so they can be retrieved once that function is called *)
   let save_params current_stmt loc args env kf =
     let (env, _) = List.fold_left
-      (fun (env, index) param ->
-        let lv = Mem(param), NoOffset in
-        let ltype = Cil.typeOf param in
-        let vals = assign ~ltype lv param loc in
-        Extlib.may_map
-          (fun (_, rhs, flow) ->
-            let env =
-              if Mmodel_analysis.must_model_exp ~kf param then
-                let stmt = Mk.save_param ~loc flow rhs index in
-                Env.add_stmt ~before:current_stmt ~post:false env kf stmt
-              else env
-            in
-            (env, index+1))
-          ~dft:(env, index+1)
-          vals)
-      (env, 0)
-      args
+        (fun (env, index) param ->
+           let lv = Mem(param), NoOffset in
+           let ltype = Cil.typeOf param in
+           let vals = assign ~ltype lv param loc in
+           Extlib.may_map
+             (fun (_, rhs, flow) ->
+                let env =
+                  if Mmodel_analysis.must_model_exp ~kf param then
+                    let stmt = Mk.save_param ~loc flow rhs index in
+                    Env.add_stmt ~before:current_stmt ~post:false env kf stmt
+                  else env
+                in
+                (env, index+1))
+             ~dft:(env, index+1)
+             vals)
+        (env, 0)
+        args
     in env
 
   (* Update local environment with a statement tracking temporal metadata
      associated with assignment [ret] = [func(args)]. *)
   let call_with_ret ?(alloc=false) current_stmt loc ret env kf =
-    let rhs = Constructor.mk_lval ~loc ret in
+    let rhs = Smart_exp.lval ~loc ret in
     let vals = assign ret rhs loc in
     (* Track referent numbers of assignments via function calls.
        Library functions (i.e., with no source code available) that return
@@ -282,17 +283,17 @@ end = struct
        [pull_return] added via a call to [Mk.handle_return_referent] *)
     Extlib.may_map
       (fun (lhs, rhs, flow) ->
-        let flow, rhs = match flow with
-          | Indirect when alloc -> Direct, (Constructor.mk_deref ~loc rhs)
-          | _ -> flow, rhs
-        in
-        let stmt =
-          if alloc then
-            Mk.store_reference ~loc flow lhs rhs
-          else
-            Mk.handle_return_referent ~save:false ~loc (Cil.mkAddrOf ~loc lhs)
-        in
-        Env.add_stmt ~before:current_stmt ~post:true env kf stmt)
+         let flow, rhs = match flow with
+           | Indirect when alloc -> Direct, (Smart_exp.deref ~loc rhs)
+           | _ -> flow, rhs
+         in
+         let stmt =
+           if alloc then
+             Mk.store_reference ~loc flow lhs rhs
+           else
+             Mk.handle_return_referent ~save:false ~loc (Cil.mkAddrOf ~loc lhs)
+         in
+         Env.add_stmt ~before:current_stmt ~post:true env kf stmt)
       ~dft:env
       vals
 
@@ -305,7 +306,7 @@ end = struct
         | _ -> Options.fatal "[Temporal.call_memxxx] not a left-value"
       in
       let stmt =
-        Constructor.mk_lib_call ~loc (RTL.mk_temporal_name name) args
+        Smart_stmt.lib_call ~loc (RTL.mk_temporal_name name) args
       in
       Env.add_stmt ~before:current_stmt ~post:false env kf stmt
     else
@@ -320,7 +321,7 @@ end = struct
        the implementation of the function should be empty and compiler should
        be able to optimize that code out. *)
     let name = (RTL.mk_temporal_name "reset_parameters") in
-    let stmt = Constructor.mk_lib_call ~loc name [] in
+    let stmt = Smart_stmt.lib_call ~loc name [] in
     let env = Env.add_stmt ~before:current_stmt ~post:false env kf stmt in
     let stmt = Mk.reset_return_referent ~loc in
     let env = Env.add_stmt ~before:current_stmt ~post:false env kf stmt in
@@ -340,9 +341,9 @@ end = struct
     let alloc = not has_def in
     Extlib.may_map
       (fun lhs ->
-        if Mmodel_analysis.must_model_lval ~kf lhs then
-          call_with_ret ~alloc current_stmt loc lhs env kf
-        else env)
+         if Mmodel_analysis.must_model_lval ~kf lhs then
+           call_with_ret ~alloc current_stmt loc lhs env kf
+         else env)
       ~dft:env
       ret
 end
@@ -465,15 +466,15 @@ let mk_global_init ~loc vi off init =
      corresponding variable which that literal string has been converted to *)
   let exp =
     try let rec get_string e = match e.enode with
-      | Const(CStr str) -> str
-      | CastE(_, exp) -> get_string exp
-      | _ -> raise Not_found
-    in
-    let str = get_string exp in
-    Cil.evar ~loc (Literal_strings.find str)
-  with
+        | Const(CStr str) -> str
+        | CastE(_, exp) -> get_string exp
+        | _ -> raise Not_found
+      in
+      let str = get_string exp in
+      Cil.evar ~loc (Literal_strings.find str)
+    with
     (* Not a literal string: just use the expression at hand *)
-    Not_found -> exp
+      Not_found -> exp
   in
   (* The input [vi] is from the old project, so get the corresponding variable
      from the new one, otherwise AST integrity is violated *)
@@ -488,15 +489,15 @@ let mk_global_init ~loc vi off init =
 let handle_function_parameters kf env =
   if is_enabled () then
     let env, _ = List.fold_left
-      (fun (env, index) param ->
-        let env =
-          if Mmodel_analysis.must_model_vi ~kf param
-          then track_argument param index env kf
-          else env
-        in
-        env, index + 1)
-      (env, 0)
-      (Kernel_function.get_formals kf)
+        (fun (env, index) param ->
+           let env =
+             if Mmodel_analysis.must_model_vi ~kf param
+             then track_argument param index env kf
+             else env
+           in
+           env, index + 1)
+        (env, 0)
+        (Kernel_function.get_formals kf)
     in env
   else
     env
@@ -505,8 +506,8 @@ let handle_stmt stmt env kf =
   if is_enabled () then begin
     match stmt.skind with
     | Instr instr -> handle_instruction stmt instr env kf
-    | Return(ret, loc) -> Extlib.may_map
-      (fun ret -> handle_return_stmt loc ret env kf) ~dft:env ret
+    | Return(ret, loc) ->
+      Extlib.may_map (fun ret -> handle_return_stmt loc ret env kf) ~dft:env ret
     | Goto _ | Break _ | Continue _ | If _ | Switch _ | Loop _ | Block _
     | UnspecifiedSequence _ | Throw _ | TryCatch _ | TryFinally _
     | TryExcept _ -> env
diff --git a/src/plugins/e-acsl/src/code_generator/temporal.mli b/src/plugins/e-acsl/src/code_generator/temporal.mli
index 087683efea0f91666aa6e29ad8d8b3f98fe1179d..469df071656ebe7278c7090343e8ab85e3a71959 100644
--- a/src/plugins/e-acsl/src/code_generator/temporal.mli
+++ b/src/plugins/e-acsl/src/code_generator/temporal.mli
@@ -43,8 +43,8 @@ val handle_stmt: stmt -> Env.t -> kernel_function -> Env.t
     properties of memory blocks *)
 
 val generate_global_init: varinfo -> offset -> init -> stmt option
-  (** Generate [Some s], where [s] is a statement tracking global initializer
-      or [None] if there is no need to track it *)
+(** Generate [Some s], where [s] is a statement tracking global initializer
+    or [None] if there is no need to track it *)
 
 (*
 Local Variables:
diff --git a/src/plugins/e-acsl/src/code_generator/translate.ml b/src/plugins/e-acsl/src/code_generator/translate.ml
index 009763c7931d6f8d47f548698052917a7551ed21..2df14a6f11f222d8a098245d820b8623e232d83d 100644
--- a/src/plugins/e-acsl/src/code_generator/translate.ml
+++ b/src/plugins/e-acsl/src/code_generator/translate.ml
@@ -141,7 +141,7 @@ let add_cast ~loc ?name env kf ctx strnum t_opt e =
             None
             new_ty
             (fun v _ ->
-               [ Constructor.mk_lib_call ~loc ~result:(Cil.var v) fname [ e ] ])
+               [ Smart_stmt.lib_call ~loc ~result:(Cil.var v) fname [ e ] ])
         in
         e, env
       else if Gmp_types.Q.is_t ty || strnum = Str_R then
@@ -229,7 +229,7 @@ let conditional_to_exp ?(name="if") loc kf t_opt e1 (e2, env2) (e3, env3) =
              let s = affect e3 in
              Env.pop_and_get env3 s ~global_clear:false Env.Middle
            in
-           [ Constructor.mk_if ~loc ~cond:e1 then_blk ~else_blk ])
+           [ Smart_stmt.if_stmt ~loc ~cond:e1 then_blk ~else_blk ])
     in
     e, env
 
@@ -276,7 +276,7 @@ and context_insensitive_term_to_exp kf env t =
     c, env, strnum, ""
   | TLval lv ->
     let lv, env, name = tlval_to_lval kf env lv in
-    Constructor.mk_lval ~loc lv, env, C_number, name
+    Smart_exp.lval ~loc lv, env, C_number, name
   | TSizeOf ty -> Cil.sizeOf ~loc ty, env, C_number, "sizeof"
   | TSizeOfE t ->
     let e, env = term_to_exp kf env t in
@@ -303,7 +303,7 @@ and context_insensitive_term_to_exp kf env t =
           kf
           ~name:vname
           (Some t)
-          (fun _ ev -> [ Constructor.mk_lib_call ~loc name [ ev; e ] ])
+          (fun _ ev -> [ Smart_stmt.lib_call ~loc name [ ev; e ] ])
       in
       e, env, C_number, ""
     else if Gmp_types.Q.is_t ty then
@@ -332,7 +332,7 @@ and context_insensitive_term_to_exp kf env t =
     let e2, env = term_to_exp kf env t2 in
     if Gmp_types.Z.is_t ty then
       let name = name_of_mpz_arith_bop bop in
-      let mk_stmts _ e = [ Constructor.mk_lib_call ~loc name [ e; e1; e2 ] ] in
+      let mk_stmts _ e = [ Smart_stmt.lib_call ~loc name [ e; e1; e2 ] ] in
       let name = Misc.name_of_binop bop in
       let _, e, env =
         Env.new_var_and_mpz_init ~loc ~name env kf (Some t) mk_stmts
@@ -370,14 +370,14 @@ and context_insensitive_term_to_exp kf env t =
       let mk_stmts _v e =
         assert (Gmp_types.Z.is_t ty);
         let cond =
-          Constructor.mk_runtime_check
+          Smart_stmt.runtime_check
             (Env.annotation_kind env)
             kf
             guard
             p
         in
         Env.add_assert kf cond p;
-        let instr = Constructor.mk_lib_call ~loc name [ e; e1; e2 ] in
+        let instr = Smart_stmt.lib_call ~loc name [ e; e1; e2 ] in
         [ cond; instr ]
       in
       let name = Misc.name_of_binop bop in
@@ -435,7 +435,7 @@ and context_insensitive_term_to_exp kf env t =
             (fun vi _e ->
                let result = Cil.var vi in
                let fname = "__gmpz_fits_ulong_p" in
-               [ Constructor.mk_lib_call ~loc ~result fname [ e2 ] ])
+               [ Smart_stmt.lib_call ~loc ~result fname [ e2 ] ])
         in
         e, env
       in
@@ -454,8 +454,8 @@ and context_insensitive_term_to_exp kf env t =
           in
           let pname = bop_name ^ "_rhs_fits_in_mp_bitcnt_t" in
           let pred = { pred with pred_name = pname :: pred.pred_name } in
-          let cond = Constructor.mk_runtime_check
-              Constructor.RTE
+          let cond = Smart_stmt.runtime_check
+              Smart_stmt.RTE
               kf
               coerce_guard
               pred
@@ -465,7 +465,7 @@ and context_insensitive_term_to_exp kf env t =
         in
         let result = Cil.var vi in
         let name = "__gmpz_get_ui" in
-        let instr = Constructor.mk_lib_call ~loc ~result name [ e2 ] in
+        let instr = Smart_stmt.lib_call ~loc ~result name [ e2 ] in
         [ coerce_guard_cond; instr ]
       in
       let name = e2_name ^ bop_name ^ "_coerced" in
@@ -484,7 +484,7 @@ and context_insensitive_term_to_exp kf env t =
       (* Create the shift instruction *)
       let mk_shift_instr result_e =
         let name = name_of_mpz_arith_bop bop in
-        Constructor.mk_lib_call ~loc name [ result_e; e1; e2_as_bitcnt_e ]
+        Smart_stmt.lib_call ~loc name [ result_e; e1; e2_as_bitcnt_e ]
       in
 
       (* Put t in an option to use with comparison_to_exp and
@@ -515,8 +515,8 @@ and context_insensitive_term_to_exp kf env t =
           in
           let e1_guard_cond =
             let pred = Logic_const.prel ~loc (Rge, t1, zero) in
-            let cond = Constructor.mk_runtime_check
-                Constructor.RTE
+            let cond = Smart_stmt.runtime_check
+                Smart_stmt.RTE
                 kf
                 e1_guard
                 pred
@@ -568,7 +568,7 @@ and context_insensitive_term_to_exp kf env t =
     if Gmp_types.Z.is_t ty then
       let mk_stmts _v e =
         let name = name_of_mpz_arith_bop bop in
-        let instr = Constructor.mk_lib_call ~loc name [ e; e1; e2 ] in
+        let instr = Smart_stmt.lib_call ~loc name [ e; e1; e2 ] in
         [ instr ]
       in
       let name = Misc.name_of_binop bop in
@@ -646,7 +646,7 @@ and context_insensitive_term_to_exp kf env t =
           (Some t)
           (Misc.cty (Extlib.the li.l_type))
           (fun vi _ ->
-             [ Constructor.mk_lib_call ~loc ~result:(Cil.var vi) fname args ])
+             [ Smart_stmt.lib_call ~loc ~result:(Cil.var vi) fname args ])
       else
         (* build the arguments and compute the integer_ty of the parameters *)
         let params_ty, args, env =
@@ -788,7 +788,7 @@ and comparison_to_exp
             ~name
             Cil.intType
             (fun v _ ->
-               [ Constructor.mk_lib_call ~loc
+               [ Smart_stmt.lib_call ~loc
                    ~result:(Cil.var v)
                    "__gmpz_cmp"
                    [ e1; e2 ] ])
@@ -855,7 +855,7 @@ and env_of_li li kf env loc =
   let e, env = term_to_exp kf env t in
   let stmt = match Typing.get_number_ty t with
     | Typing.(C_integer _ | C_float _ | Nan) ->
-      Constructor.mk_assigns ~loc ~result:(Cil.var vi) e
+      Smart_stmt.assigns ~loc ~result:(Cil.var vi) e
     | Typing.Gmpz ->
       Gmp.init_set ~loc (Cil.var vi) vi_e e
     | Typing.Rational ->
@@ -1033,7 +1033,7 @@ and translate_rte_annots:
   fun pp elt kf env l ->
   let old_valid = !is_visiting_valid in
   let old_kind = Env.annotation_kind env in
-  let env = Env.set_annotation_kind env Constructor.RTE in
+  let env = Env.set_annotation_kind env Smart_stmt.RTE in
   let env =
     List.fold_left
       (fun env a -> match a.annot_content with
@@ -1078,7 +1078,7 @@ and translate_named_predicate kf env p =
   Env.add_stmt
     env
     kf
-    (Constructor.mk_runtime_check
+    (Smart_stmt.runtime_check
        (Env.annotation_kind env)
        kf
        e
@@ -1168,7 +1168,7 @@ let assumes_predicate bhv =
     bhv.b_assumes
 
 let translate_preconditions kf kinstr env behaviors =
-  let env = Env.set_annotation_kind env Constructor.Precondition in
+  let env = Env.set_annotation_kind env Smart_stmt.Precondition in
   let do_behavior env b =
     let assumes_pred = assumes_predicate b in
     List.fold_left
@@ -1193,7 +1193,7 @@ let translate_preconditions kf kinstr env behaviors =
   List.fold_left do_behavior env behaviors
 
 let translate_postconditions kf kinstr env behaviors =
-  let env = Env.set_annotation_kind env Constructor.Postcondition in
+  let env = Env.set_annotation_kind env Smart_stmt.Postcondition in
   (* generate one guard by postcondition of each behavior *)
   let do_behavior env b =
     let env =
@@ -1284,7 +1284,7 @@ let translate_pre_code_annotation kf stmt env annot =
   let convert env = match annot.annot_content with
     | AAssert(l, _, p) ->
       if must_translate (Property.ip_of_code_annot_single kf stmt annot) then
-        let env = Env.set_annotation_kind env Constructor.Assertion in
+        let env = Env.set_annotation_kind env Smart_stmt.Assertion in
         if l <> [] then
           not_yet env "@[assertion applied only on some behaviors@]";
         translate_named_predicate kf env p
@@ -1296,7 +1296,7 @@ let translate_pre_code_annotation kf stmt env annot =
       translate_pre_spec kf (Kstmt stmt) env spec ;
     | AInvariant(l, loop_invariant, p) ->
       if must_translate (Property.ip_of_code_annot_single kf stmt annot) then
-        let env = Env.set_annotation_kind env Constructor.Invariant in
+        let env = Env.set_annotation_kind env Smart_stmt.Invariant in
         if l <> [] then
           not_yet env "@[invariant applied only on some behaviors@]";
         let env = translate_named_predicate kf env p in
diff --git a/src/plugins/e-acsl/src/libraries/misc.ml b/src/plugins/e-acsl/src/libraries/misc.ml
index 0b2cd0d3ad79f9a6f08f442da392e7013fd38041..284d57621d5e2f242f8ada787f1acc8c0d8648af 100644
--- a/src/plugins/e-acsl/src/libraries/misc.ml
+++ b/src/plugins/e-acsl/src/libraries/misc.ml
@@ -189,6 +189,15 @@ module Id_term =
       let mem_project = Datatype.never_any_project
     end)
 
+let extract_uncoerced_lval e =
+  let rec aux e =
+    match e.enode with
+    | Lval _ -> Some e
+    | CastE (_, e) -> aux e
+    | _ -> None
+  in
+  aux e
+
 (*
 Local Variables:
 compile-command: "make -C ../../../../.."
diff --git a/src/plugins/e-acsl/src/libraries/misc.mli b/src/plugins/e-acsl/src/libraries/misc.mli
index f9c92c19e8097a872a37edc83fa83301a79dd645..6ea105fd88a00e4e4c3621fc90511f9eb943bdc0 100644
--- a/src/plugins/e-acsl/src/libraries/misc.mli
+++ b/src/plugins/e-acsl/src/libraries/misc.mli
@@ -81,6 +81,13 @@ val finite_min_and_max: Ival.t -> Integer.t * Integer.t
 module Id_term: Datatype.S_with_collections with type t = term
 (** Datatype for terms that relies on physical equality. *)
 
+val extract_uncoerced_lval: exp -> exp option
+(** Unroll the [CastE] part of the expression until an [Lval] is found, and
+    return it.
+
+    If at some point the expression is neither a [CastE] nor an [Lval], then
+    return [None]. *)
+
 (*
 Local Variables:
 compile-command: "make -C ../../../../.."