diff --git a/src/plugins/e-acsl/Makefile.in b/src/plugins/e-acsl/Makefile.in
index 67badd902929239d8d609c12369c336bd1f4779d..ee12b9ccfad66a1cdbf93dfaa9dafb1ff3cfa4f5 100644
--- a/src/plugins/e-acsl/Makefile.in
+++ b/src/plugins/e-acsl/Makefile.in
@@ -178,53 +178,6 @@ e-acsl-distclean::
 		then $(MAKE) -s -C$(EACSL_GMP_DIR) distclean; \
 	fi
 
-################################################
-# E-ACSL Runtime Library                       #
-################################################
-
-EACSL_SHARE := $(EACSL_PLUGIN_DIR)/share/e-acsl
-
-EACSL_RTL_SRC = $(wildcard $(EACSL_SHARE)/*.[ch] $(EACSL_SHARE)/*/*.[ch])
-
-RTLFLAGS = -std=c99 -Wall -Wno-unused -Wno-attributes -I$(EACSL_SHARE) \
-  -fno-omit-frame-pointer -DE_ACSL_BUILTINS -Wno-nonnull
-
-RTLOPT 	 = $(RTLFLAGS) -O2
-RTLDEBUG = $(RTLFLAGS) -DE_ACSL_DEBUG -g3 -O0
-
-# Build a static E-ACSL library
-  # $1 Compile-time flags
-  # $2 Library path
-  # $3 Source file
-MKRTL = \
-  echo "Making $2"; \
-  object=$$(basename -s .a $2).o && \
-  echo ' CC $3' && \
-  $(CC) $1 -c -o$$object $3 && \
-  echo ' AR $2' && \
-  $(AR) crus $2 $$object && \
-  $(RM) -f $$object && \
-  ranlib $2
-
-$(EACSL_LIBDIR)/libeacsl-rtl-%.a: $(EACSL_SHARE)/%_model/e_acsl_*_mmodel.c $(EACSL_RTL_SRC) $(EACSL_JEMALLOC_LIB) $(EACSL_GMP_LIB)
-	$(call MKRTL, $(RTLOPT), $@, $<)
-
-$(EACSL_LIBDIR)/libeacsl-rtl-%-dbg.a: $(EACSL_SHARE)/%_model/e_acsl_*_mmodel.c $(EACSL_RTL_SRC) $(EACSL_JEMALLOC_LIB) $(EACSL_GMP_LIB)
-	$(call MKRTL, $(RTLDEBUG), $@, $<)
-
-EACSL_RTL = \
-	$(EACSL_LIBDIR)/libeacsl-rtl-bittree.a \
-	$(EACSL_LIBDIR)/libeacsl-rtl-segment.a \
-	$(EACSL_LIBDIR)/libeacsl-rtl-bittree-dbg.a \
-	$(EACSL_LIBDIR)/libeacsl-rtl-segment-dbg.a
-
-clean::
-	$(PRINT_RM) E-ACSL runtime library
-	$(RM) $(EACSL_RTL)
-	$(RM) $(EACSL_LIBDIR)/*.o
-
-all:: $(EACSL_RTL)
-
 ############
 # Cleaning #
 ############
@@ -371,10 +324,14 @@ install::
 	$(MKDIR) $(FRAMAC_DATADIR)/e-acsl
 	$(CP) $(E_ACSL_DIR)/share/e-acsl/*.[ch] $(FRAMAC_DATADIR)/e-acsl
 	$(MKDIR) $(FRAMAC_DATADIR)/e-acsl/bittree_model \
-		 $(FRAMAC_DATADIR)/e-acsl/glibc
+	         $(FRAMAC_DATADIR)/e-acsl/segment_model \
+	         $(FRAMAC_DATADIR)/e-acsl/glibc
 	$(CP) $(E_ACSL_DIR)/share/e-acsl/bittree_model/* \
-		$(FRAMAC_DATADIR)/e-acsl/bittree_model
-	$(CP) $(E_ACSL_DIR)/share/e-acsl/glibc/* $(FRAMAC_DATADIR)/e-acsl/glibc
+	      $(FRAMAC_DATADIR)/e-acsl/bittree_model
+	$(CP) $(E_ACSL_DIR)/share/e-acsl/segment_model/* \
+	      $(FRAMAC_DATADIR)/e-acsl/segment_model
+	$(CP) $(E_ACSL_DIR)/share/e-acsl/glibc/* \
+	      $(FRAMAC_DATADIR)/e-acsl/glibc
 	$(PRINT_INSTALL) E-ACSL manuals
 	$(MKDIR) $(FRAMAC_DATADIR)/manuals
 	$(CP) $(E_ACSL_DIR)/doc/manuals/e-acsl.pdf \
diff --git a/src/plugins/e-acsl/misc.ml b/src/plugins/e-acsl/misc.ml
index 5c6d57f6a4e517c9c31e35cd11c0edd5a4aae949..a1e78558beae129f7a85f2585ae7f97bfeb01764 100644
--- a/src/plugins/e-acsl/misc.ml
+++ b/src/plugins/e-acsl/misc.ml
@@ -63,25 +63,29 @@ let mk_call ~loc ?result fname args =
   in
   let f = Cil.evar ~loc vi in
   vi.vreferenced <- true;
-  let ty_params = match vi.vtype with
-    | TFun(_, Some l, _, _) -> l
-    | _ -> assert false
-  in
-  let args =
+  let make_args args ty_params =
     List.map2
       (fun (_, ty, _) arg ->
-	let e =
-	  match ty, Cil.unrollType (Cil.typeOf arg), arg.enode with
-	  | TPtr _, TArray _, Lval lv -> Cil.new_exp ~loc (StartOf lv)
-	  | TPtr _, TArray _, _ -> assert false
-	  | _, _, _ -> arg
-	in
-	Cil.mkCast ~force:false ~newt:ty ~e)
+        let e =
+          match ty, Cil.unrollType (Cil.typeOf arg), arg.enode with
+          | TPtr _, TArray _, Lval lv -> Cil.new_exp ~loc (StartOf lv)
+          | TPtr _, TArray _, _ -> assert false
+          | _, _, _ -> arg
+        in
+        Cil.mkCast ~force:false ~newt:ty ~e)
       ty_params
       args
   in
+  let args = match vi.vtype with
+    | TFun(_, Some params, _, _) -> make_args args params
+    | TFun(_, None, _, _) -> []
+    | _ -> assert false
+  in
   Cil.mkStmtOneInstr ~valid_sid:true (Call(result, f, args, loc))
 
+let mk_deref ~loc lv =
+  Cil.new_exp ~loc (Lval(Mem(lv), NoOffset))
+
 type annotation_kind =
   | Assertion
   | Precondition
@@ -125,6 +129,9 @@ let strip_prefix p s =
 let is_generated_varinfo vi =
   startswith e_acsl_gen_prefix vi.vname
 
+let is_generated_literal_string_varinfo vi =
+  startswith (e_acsl_gen_prefix ^ "literal_string") vi.vname
+
 let is_library_name name =
   startswith e_acsl_api_prefix name
 
@@ -197,23 +204,12 @@ let result_vi kf = match result_lhost kf with
 (** {2 Handling the E-ACSL's C-libraries, part II} *)
 (* ************************************************************************** *)
 
-let mk_debug_mmodel_stmt stmt =
-  if Options.debug_atleast 1
-    && Options.is_debug_key_enabled Options.dkey_analysis
-  then
-    let debug = mk_call ~loc:(Stmt.loc stmt) (mk_api_name "memory_debug") [] in
-    Cil.mkStmt ~valid_sid:true (Block (Cil.mkBlock [ stmt; debug]))
-  else
-    stmt
-
 let mk_full_init_stmt ?(addr=true) vi =
   let loc = vi.vdecl in
-  let stmt = match addr, Cil.unrollType vi.vtype with
+  match addr, Cil.unrollType vi.vtype with
     | _, TArray(_,Some _, _, _) | false, _ ->
       mk_call ~loc (mk_api_name "full_init") [ Cil.evar ~loc vi ]
     | _ -> mk_call ~loc (mk_api_name "full_init") [ Cil.mkAddrOfVi vi ]
-  in
-  mk_debug_mmodel_stmt stmt
 
 let mk_initialize ~loc (host, offset as lv) = match host, offset with
   | Var _, NoOffset -> mk_call ~loc
@@ -229,14 +225,12 @@ let mk_named_store_stmt name ?str_size vi =
   let ty = Cil.unrollType vi.vtype in
   let loc = vi.vdecl in
   let store = mk_call ~loc (mk_api_name name) in
-  let stmt = match ty, str_size with
+  match ty, str_size with
     | TArray(_, Some _,_,_), None ->
       store [ Cil.evar ~loc vi ; Cil.sizeOf ~loc ty ]
     | TPtr(TInt(IChar, _), _), Some size -> store [ Cil.evar ~loc vi ; size ]
     | _, None -> store [ Cil.mkAddrOfVi vi ; Cil.sizeOf ~loc ty ]
     | _, Some _ -> assert false
-  in
-  mk_debug_mmodel_stmt stmt
 
 let mk_store_stmt ?str_size vi =
   mk_named_store_stmt "store_block" ?str_size vi
@@ -246,17 +240,14 @@ let mk_duplicate_store_stmt ?str_size vi =
 
 let mk_delete_stmt vi =
   let loc = vi.vdecl in
-  let stmt = match Cil.unrollType vi.vtype with
+  match Cil.unrollType vi.vtype with
     | TArray(_, Some _, _, _) ->
       mk_call ~loc (mk_api_name "delete_block") [ Cil.evar ~loc vi ]
     | _ -> mk_call ~loc (mk_api_name "delete_block") [ Cil.mkAddrOfVi vi ]
-  in
-  mk_debug_mmodel_stmt stmt
 
-let mk_readonly vi =
+let mk_mark_readonly vi =
   let loc = vi.vdecl in
-  let stmt = mk_call ~loc (mk_api_name "readonly") [ Cil.evar ~loc vi ] in
-  mk_debug_mmodel_stmt stmt
+  mk_call ~loc (mk_api_name "mark_readonly") [ Cil.evar ~loc vi ]
 
 (* ************************************************************************** *)
 (** {2 Other stuff} *)
@@ -279,6 +270,29 @@ let cty = function
   | Ctype ty -> ty
   | lty -> Options.fatal "Expecting a C type. Got %a" Printer.pp_logic_type lty
 
+let rec ptr_index ?(loc=Location.unknown) ?(index=(Cil.zero loc)) exp =
+  let arith_op = function
+    | MinusPI -> MinusA
+    | PlusPI -> PlusA
+    | IndexPI -> PlusA
+    | _ -> assert false in
+  match exp.enode with
+  | BinOp(op, lhs, rhs, _) ->
+    (match op with
+    (* Pointer arithmetic: split pointer and integer parts *)
+    | MinusPI | PlusPI | IndexPI ->
+      let index = Cil.mkBinOp exp.eloc (arith_op op) index rhs in
+      ptr_index ~index lhs
+    (* Other arithmetic: treat the whole expression as pointer address *)
+    | MinusPP | PlusA | MinusA | Mult | Div | Mod
+    | BAnd | BXor | BOr | Shiftlt | Shiftrt
+    | Lt | Gt | Le | Ge | Eq | Ne | LAnd | LOr -> (exp, index))
+  | CastE _ -> ptr_index ~loc ~index (Cil.stripCasts exp)
+  | Info (exp, _) -> ptr_index ~loc ~index exp
+  | Const _ | StartOf _ | AddrOf _ | Lval _ | UnOp _ -> (exp, index)
+  | SizeOf _ | SizeOfE _ | SizeOfStr _ | AlignOf _ | AlignOfE _
+    -> assert false
+
 (*
 Local Variables:
 compile-command: "make"
diff --git a/src/plugins/e-acsl/misc.mli b/src/plugins/e-acsl/misc.mli
index e9de1d3662c1aae4f9ea27c5e320add1ace87d82..10a2a111be7c8d3101a0eb0db7705ca7a8fde82d 100644
--- a/src/plugins/e-acsl/misc.mli
+++ b/src/plugins/e-acsl/misc.mli
@@ -36,7 +36,8 @@ val mk_call: loc:Location.t -> ?result:lval -> string -> exp list -> stmt
     such a function or if these functions were never registered (only possible
     when using E-ACSL through its API. *)
 
-val mk_debug_mmodel_stmt: stmt -> stmt
+val mk_deref: loc:Location.t -> exp -> exp
+(** Make a dereference of an expression *)
 
 type annotation_kind =
   | Assertion
@@ -75,7 +76,7 @@ val mk_duplicate_store_stmt: ?str_size:exp -> varinfo -> stmt
 val mk_delete_stmt: varinfo -> stmt
 val mk_full_init_stmt: ?addr:bool -> varinfo -> stmt
 val mk_initialize: loc:location -> lval -> stmt
-val mk_readonly: varinfo -> stmt
+val mk_mark_readonly: varinfo -> stmt
 
 (* ************************************************************************** *)
 (** {2 Other stuff} *)
@@ -91,6 +92,11 @@ val reorder_ast: unit -> unit
 val cty: logic_type -> typ
 (* Assume that the logic type is indeed a C type. Just return it. *)
 
+val ptr_index: ?loc:location -> ?index:exp -> exp
+  -> Cil_types.exp * Cil_types.exp
+(** Split pointer-arithmetic expression of the type `p + i` into its
+pointer and integer parts. *)
+
 (* ************************************************************************** *)
 (** {2 Handling prefixes of generated library functions and variables} *)
 (* ************************************************************************** *)
@@ -113,6 +119,10 @@ val is_generated_varinfo: varinfo -> bool
    generated by E-ACSL. This is done by checking whether the name of the
    varinfo has been generated using [mk_gen_name function]. *)
 
+val is_generated_literal_string_varinfo: varinfo -> bool
+(** Same as [is_generated_varinfo] but indicates that varinfo is a local
+   variable which replaced a literal string. *)
+
 val is_generated_kf: kernel_function -> bool
 (** Same as [is_generated_varinfo] but for kernel functions *)
 
diff --git a/src/plugins/e-acsl/scripts/e-acsl-gcc.sh b/src/plugins/e-acsl/scripts/e-acsl-gcc.sh
index 89405b75fda5d4888813fc957a598e492975ee56..fd3343162679b54d84755f5fb3435894d1928b90 100755
--- a/src/plugins/e-acsl/scripts/e-acsl-gcc.sh
+++ b/src/plugins/e-acsl/scripts/e-acsl-gcc.sh
@@ -149,41 +149,20 @@ rte_options() {
   return 0
 }
 
-# Locate available E-ACSL memory models
-# - If no arguments are given then print the names of all memory models
-#    available in this distribution of E-ACSL.
-# - If an argument is specified then it is assumed to be the name of a memory
-#    model. In this case the following function prints the full path to a static
-#    library representing this memory model.
-mmodel_lib() {
-  local rtfeature=""
+# Output -D flags enabling a given E_ACSL memory model
+eacsl_mmodel() {
+  local model="$1"
+
+  case $model in
+    bittree) flags="-DE_ACSL_BITTREE_MMODEL" ;;
+    segment) flags="-DE_ACSL_SEGMENT_MMODEL" ;;
+    *) error "Memory model '$model' is not available in this distribution" ;;
+  esac
   if [ -n "$OPTION_RT_DEBUG" ]; then
-    rtfeature="-dbg"
-    OPTION_CFLAGS="$OPTION_CFLAGS -O0 -fno-omit-frame-pointer"
-  else
-    OPTION_CFLAGS="$OPTION_CFLAGS -O2"
-  fi
-
-  # Supported models
-  local models="segment bittree"
-
-  if [ -n "$1" ]; then
-    local modelname="$(echo $models | tr ' ' '\n' | grep "^$1$")"
-    local modelpath="$(realpath "$LIBDIR/libeacsl-rtl-$modelname$rtfeature.a" 2>/dev/null)"
-
-    # Bail if the name of the specified memory model does not match any of the
-    # supported ones
-    if [ -z "$modelname" ]; then
-      error "Memory model '$1' is not available in this distribution"
-    fi
-    # Bail if the library for a specified memory model is not found
-    if [ -z "$modelpath" ]; then
-      error "Library '$modelpath' not found"
-    fi
-    echo $modelpath
-  else
-    echo $models
+    flags="$flags -DE_ACSL_DEBUG"
   fi
+  local extra="-DE_ACSL_IDENTIFY"
+  echo $flags $extra
 }
 
 # Check if the following tools are GNU and abort otherwise
@@ -220,13 +199,16 @@ OPTION_FRAMA_STDLIB="-no-frama-c-stdlib" # Use Frama-C stdlib
 OPTION_FULL_MMODEL=                      # Instrument as much as possible
 OPTION_GMP=                              # Use GMP integers everywhere
 OPTION_FRAMAC_CPP_EXTRA="-D__NO_CTYPE"   # Extra CPP flags for Frama-C*
-OPTION_EACSL_MMODELS="bittree"           # Memory model used
+OPTION_EACSL_MMODELS="segment"           # Memory model used
 OPTION_EACSL_SHARE=                      # Custom E-ACSL share directory
 OPTION_INSTRUMENTED_ONLY=                # Do not compile original code
 OPTION_RTE=                              # Enable assertion generation
 OPTION_CHECK=                            # Check AST integrity
 OPTION_RTE_SELECT=               # Generate assertions for these functions only
 
+# Supported memory model names
+SUPPORTED_MMODELS="bittree,segment"
+
 manpage() {
   printf "e-acsl-gcc.sh - instrument and compile C files with E-ACSL
 Usage: e-acsl-gcc.sh [options] files
@@ -448,7 +430,7 @@ do
     # Print names of the supported memody models.
     --print-mmodels)
       shift;
-      mmodel_lib
+      echo $SUPPORTED_MMODELS
       exit 0
     ;;
   esac
@@ -518,15 +500,18 @@ if [ -n "$OPTION_EACSL_SHARE" ]; then
   EACSL_SHARE="$OPTION_EACSL_SHARE"
 fi
 
-# Once EACSL_SHARE is defined check the memory models provided at inputs
-for mod in $OPTION_EACSL_MMODELS; do
-  mmodel_lib $mod >/dev/null
-done
+# Select optimization flags for both instrumented and noon-instrumented code
+# compilation
+if [ -n "$OPTION_RT_DEBUG" ]; then
+  OPT_CFLAGS="-g3 -O0 -fno-omit-frame-pointer"
+else
+  OPT_CFLAGS="-g -O2"
+fi
 
 # Gcc and related flags
 CC="$OPTION_CC"
 CFLAGS="$OPTION_CFLAGS
-  -std=c99 $GCCMACHDEP -g3
+  -std=c99 $GCCMACHDEP $OPT_CFLAGS
   -fno-builtin -fno-merge-constants
   -Wall \
   -Wno-long-long \
@@ -618,19 +603,21 @@ if [ -n "$OPTION_COMPILE" ]; then
   fi
 
   # Compile and link E-ACSL-instrumented file with all models specified
-  for mod in $OPTION_EACSL_MMODELS; do
+  for model in $OPTION_EACSL_MMODELS; do
     # If multiple models are specified then the generated executable
     # is appended a '-MODEL' suffix, where MODEL is the name of the memory
     # model used
     if ! [ "`echo $OPTION_EACSL_MMODELS | wc -w`" = 1 ]; then
-      OUTPUT_EXEC="$EACSL_OUTPUT_EXEC-$mod"
+      OUTPUT_EXEC="$EACSL_OUTPUT_EXEC-$model"
     else
       OUTPUT_EXEC="$EACSL_OUTPUT_EXEC"
     fi
     # Sources of the selected memory model
-    EACSL_RTL=$(mmodel_lib "$mod")
+    EACSL_RTL="$EACSL_SHARE/e_acsl_mmodel.c"
+    EACSL_MMODEL="$(eacsl_mmodel $model)"
     ($OPTION_ECHO;
      $CC \
+       $EACSL_MMODEL \
        $CFLAGS $CPPFLAGS \
        $EACSL_CFLAGS $EACSL_CPPFLAGS \
        -o "$OUTPUT_EXEC" \
diff --git a/src/plugins/e-acsl/scripts/testrun.sh b/src/plugins/e-acsl/scripts/testrun.sh
index 1365313c02e834d3813ffaaf876b0ec064d0d2c9..69407bc96ac0dc4c21699daf62c692f0e5d6ec4f 100755
--- a/src/plugins/e-acsl/scripts/testrun.sh
+++ b/src/plugins/e-acsl/scripts/testrun.sh
@@ -42,7 +42,8 @@
 #       * $ROOT/test/runtime/addrOf.c
 #   $3 - if specified, re-run test sequence with -e-acsl-gmp-only flag
 #   $4 - extra flags for a `e-acsl-gcc.sh` run
-#   $5 - if specified print extra messages and retain log files (DEBUG option)
+#   $5 - names of memory models to use
+#   $6 - if specified print extra messages and retain log files (DEBUG option)
 
 set -e
 
@@ -50,9 +51,11 @@ TEST="$1"   # Base name of the test file
 PREFIX="$2" # Test suite directory (e.g., runtime)
 GMP="$3"    # Whether to issue an additional run with -e-acsl-gmp-only
 EXTRA="$4"  # Extra e-acsl-gcc.sh flags
-DEBUG="$5"  # Debug option
+MODELS="$5" # Specify models
+DEBUG="$6"  # Debug option
 
 EACSLGCC="$(dirname $0)/e-acsl-gcc.sh $EXTRA" # E-ACSL wrapper script
+MODELS=${5-"segment bittree"} # Memory models to use (unless specified)
 
 ROOTDIR="`readlink -f $(dirname $0)/../`" # Root directory of the repository
 TESTDIR="$ROOTDIR/tests/$PREFIX" # Test suite directory
@@ -90,6 +93,8 @@ error() {
   exit 1
 }
 
+debug "Test: $PREFIX/$TEST with $MODELS"
+
 # Do a clean-up on exit
 trap "clean" EXIT HUP INT QUIT TERM
 
@@ -118,11 +123,6 @@ run_test() {
   local oexec=$OUT.$RUNS.out # Generated executable name
   local oexeclog=$LOG.$RUNS.rlog # Log for executable output
   local extra="$1" # Additional arguments to e-acsl-gcc.sh
-  MODELS="$($EACSLGCC $extra --print-mmodels)" # Supported memory models
-
-  # e-acsl-gcc.sh reports models as space-separated string. Make a
-  # comma-separated one otherwise the following does not work
-  MODELSTR="$(echo $MODELS | tr ' ' ',')"
 
   # Command for instrumenting the source file
   COMMAND="$EACSLGCC $TESTFILE --ocode=$ocode --logfile=$logfile $extra"
diff --git a/src/plugins/e-acsl/share/e-acsl/bittree_model/e_acsl_bittree_mmodel.c b/src/plugins/e-acsl/share/e-acsl/bittree_model/e_acsl_bittree_mmodel.c
index e62516c2fa143a86ea7cc919724857bfa3c95a7b..746cc75c6c26d0b95923051c5a6b5fe257020207 100644
--- a/src/plugins/e-acsl/share/e-acsl/bittree_model/e_acsl_bittree_mmodel.c
+++ b/src/plugins/e-acsl/share/e-acsl/bittree_model/e_acsl_bittree_mmodel.c
@@ -26,17 +26,6 @@
  * on Patricia Trie. See e_acsl_mmodel_api.h for details.
 ***************************************************************************/
 
-#ifndef E_ACSL_BITTREE_MMODEL
-#define E_ACSL_BITTREE_MMODEL
-
-#include "e_acsl_string.h"
-#include "e_acsl_printf.h"
-#include "e_acsl_bits.h"
-#include "e_acsl_assert.h"
-#include "e_acsl_debug.h"
-#include "e_acsl_malloc.h"
-#include "e_acsl_safe_locations.h"
-#include "e_acsl_mmodel_api.h"
 #include "e_acsl_bittree.h"
 
 /**************************/
@@ -154,7 +143,7 @@ static void full_init (void * ptr) {
 }
 
 /* mark a block as read-only */
-static void readonly(void * ptr) {
+static void mark_readonly(void * ptr) {
   bt_block * tmp;
   if (ptr == NULL)
     return;
@@ -212,22 +201,29 @@ static size_t block_length(void* ptr) {
   return tmp->size;
 }
 
+static int allocated(void* ptr, size_t size, void *ptr_base) {
+  bt_block * blk = bt_find(ptr);
+  bt_block * blk_base = bt_find(ptr_base);
+  if (blk == NULL || blk_base == NULL || blk->ptr != blk_base->ptr)
+    return false;
+  return (blk->size - ((size_t)ptr - blk->ptr) >= size);
+}
+
 /* return whether the size bytes of ptr are readable/writable */
-static int valid(void* ptr, size_t size) {
-  if(ptr == NULL)
+static int valid(void* ptr, size_t size, void *ptr_base, void *addr_of_base) {
+  /* Many similarities with allocated (so far at least), but it is better
+   * to use this tandalone definition, otherwise the block needs to be looked
+   * up twice */
+  bt_block * blk = bt_find(ptr);
+  bt_block * blk_base = bt_find(ptr_base);
+  if (blk == NULL || blk_base == NULL || blk->ptr != blk_base->ptr)
     return false;
-  bt_block * tmp = bt_find(ptr);
-  return (tmp == NULL) ? false :
-    (tmp->size - ((size_t)ptr - tmp->ptr ) >= size && !tmp->is_readonly);
+  return (blk->size - ((size_t)ptr - blk->ptr) >= size && !blk->is_readonly);
 }
 
 /* return whether the size bytes of ptr are readable */
-static int valid_read(void* ptr, size_t size) {
-  if(ptr == NULL)
-    return false;
-  bt_block * tmp = bt_find(ptr);
-  return (tmp == NULL) ?
-    false : (tmp->size - ((size_t)ptr - tmp->ptr) >= size);
+static int valid_read(void* ptr, size_t size, void *ptr_base, void *addr_of_base) {
+  return allocated(ptr, size, ptr_base);
 }
 
 /* return the base address of the block containing ptr */
@@ -394,7 +390,7 @@ static int bittree_posix_memalign(void **memptr, size_t alignment, size_t size)
     return -1;
 
   /* Make sure that the first argument to posix memalign is indeed allocated */
-  vassert(valid(memptr, sizeof(void*)),
+  vassert(allocated((void*)memptr, sizeof(void*), (void*)memptr),
       "\\invalid memptr in posix_memalign", NULL);
 
   int res = native_posix_memalign(memptr, alignment, size);
@@ -447,7 +443,7 @@ static void* bittree_realloc(void* ptr, size_t size) {
       /* allocate memory to store partial initialization */
       tmp->init_ptr = native_calloc(1, nb);
       /* carry out initialization of the old block */
-      setbits(tmp->init_ptr, tmp->size);
+      setbits(tmp->size, tmp->init_ptr);
     }
   } else { /* contains initialized and uninitialized parts */
     int nb = needed_bytes(size);
@@ -510,6 +506,7 @@ static void init_argv(int argc, char **argv) {
 }
 
 static void memory_init(int *argc_ref, char ***argv_ref, size_t ptr_size) {
+  identify_run();
   arch_assert(ptr_size);
   /* Tracking program arguments */
   if (argc_ref)
@@ -593,7 +590,7 @@ public_alias(valid)
 public_alias(block_length)
 public_alias(initialized)
 public_alias(freeable)
-public_alias(readonly)
+public_alias(mark_readonly)
 /* Block initialization */
 public_alias(initialize)
 public_alias(full_init)
@@ -611,4 +608,3 @@ public_alias(store_block_debug)
 public_alias(delete_block_debug)
 #endif
 /* }}} */
-#endif
diff --git a/src/plugins/e-acsl/share/e-acsl/e_acsl_bits.h b/src/plugins/e-acsl/share/e-acsl/e_acsl_bits.h
index 436433f27de5fdadfa34a840a032c1beb857d89a..d04144a17b0e0d71fd1e867e9d4d7bb8e6f65fd1 100644
--- a/src/plugins/e-acsl/share/e-acsl/e_acsl_bits.h
+++ b/src/plugins/e-acsl/share/e-acsl/e_acsl_bits.h
@@ -30,6 +30,9 @@
  * is, the implementation assumes that least significant bytes are stored at
  * the highest memory addresses. In future support for big-endian/PDP byte
  * orders should also be provided.
+ *
+ * CAUTION: As per above FIXME notice, all examples, macros and functions
+ * assume little-endian byte order.
 ***************************************************************************/
 
 #ifndef E_ACSL_BITS
@@ -55,34 +58,27 @@
 /* 64-bit type with all bits set to zeroes */
 #define ZERO (~ONE)
 
-/* Set a given bit in a number to '1' (least-significant bit is at index zero). *
+/* Set a given bit in a number to '1' (least-significant bit is at index zero).
  * Example:
- *  int x = 0;
- *    // x => 0000 0000 ...
- *  bitset(0, x)
- *    // x => 1000 0000 ...
- *  bitset(7, x)
- *    // x => 1000 0001 ... */
+ *  int x = 0;    // x => 0000 0000 ...
+ *  bitset(0, x)  // x => 1000 0000 ...
+ *  bitset(7, x)  // x => 1000 0001 ... */
 #define setbit(_bit,_number) (_number |= 1 << _bit)
 
-/* Same as bitset but the bit is cleared (set of zero) */
+/* Same as bitset but the `_bit` bit is cleared (i.e., set of zero) */
 #define clearbit(_bit, _number) (_number &= ~(1 << _bit))
 
-/* Evaluates to a true value if a given bit in a number is set to 1.
- *  int x = 1;
- *    // x => 1000 0000 ...
- *  checkbit(0, x) // true
- *  checkbit(1, x) // false */
+/* Evaluate to a non-zero value if a given bit in a number is set to 1.
+ *  int x = 1;     // x => 1000 0000 ...
+ *  checkbit(0, x) // 1
+ *  checkbit(1, x) // 0 */
 #define checkbit(_bit, _number) ((_number >> _bit) & 1)
 
 /* Toggle a given bit.
  * Example:
- *  int x = 4; (assume little-endian)
- *    // x => 0010 0000 ...
- *  togglebit(3, x);
- *    // x => 0000 0000 ...
- *  togglebit(3, x);
- *    // x => 0010 0000 ... */
+ *  int x = 4;        // x => 0010 0000 ...
+ *  togglebit(3, x);  // x => 0000 0000 ...
+ *  togglebit(3, x);  // x => 0010 0000 ... */
 #define togglebit(_bit, _number) (_number ^= 1 << _bit)
 
 /* Set a given bit to a specified value (e.g., 0 or 1). */
@@ -91,24 +87,47 @@
 
 /* Set up to 64 bits from left to right to ones.
  * Example:
- *  int x = 0;
- *    // x => 00000000 00000000 00000000 00000000
- *  setbits64(11, x)
- *    // => 11111111 11100000 00000000 00000000
- *  setbits64(65, x)
- *    // => behaviour undefined */
+ *  int x = 0;        // x => 00000000 00000000 ...
+ *  setbits64(11, x)  //   => 11111111 11100000 ...
+ *  setbits64(64, x)  //   => behaviour undefined */
 #define setbits64(_bits, _number)   (_number |= ~(ONE << _bits))
 
+/* Set up to 64 bits from left to right to ones skiping `_skip` leftmost bits
+ * Example:
+ *  int x = 0;          // x => 00000000 00000000 ...
+ *  setbits64(11, x, 2) //   => 00111111 11111000 ...
+ *  setbits64(64, x, 2) //   => behaviour undefined */
+#define setbits64_skip(_bits, _number, _skip) \
+  (_number |= ~(ONE << _bits) << _skip)
+
+/* Evaluate to 1 if up to 64 bits from left to right in `_number` are set:
+ * Example:
+ *  int x = 31;         // x => 11111000 00000000 ...
+ *  checkbits64(4, x)   //   => 1
+ *  checkbits64(5, x)   //   => 1
+ *  checkbits64(6, x)   //   => 0
+ *  checkbits64(64, x)  //   => behaviour undefined */
+#define checkbits64(_bits, _number) \
+  ((_number & ~(ONE << _bits)) ==  (~(ONE << _bits)))
+
+/* Same as checkbits64 but with skipping `_skip` leftmost bits
+ * Example:
+ *  int x = 124;               // x => 00111100 00000000 ...
+ *  checkbits64_skip(3,  x, 2) // => 1
+ *  checkbits64_skip(4,  x, 2) // => 1
+ *  checkbits64_skip(5,  x, 2) // => 0
+ *  checkbits64_skip(3,  x, 1) // => 0
+ *  checkbits64_skip(64, x, 0) // => behaviour undefined */
+#define checkbits64_skip(_bits, _number, _skip) \
+  ((_number & ~(ONE << _bits) << _skip) == (~(ONE << _bits) << _skip))
+
 /* Same as `setbits64' but clear the bits (set to zeroes). */
 #define clearbits64(_bits, _number) (_number &= ONE << _bits)
 
-/* Assume that `_number' is a 64-bit integral type.
- * Set `_bits' bits from right to the left starting from a 64-bit boundary.
+/* Set `_bits' bits from right to the left starting from a 64-bit boundary.
  * Example:
- *  long x = 0;
- *    // x => ... 00000000 00000000 00000000 00000000
- *  setbits64_right(10, x)
- *    // x => ... 00000000 00000000 00000011 11111111 */
+ *  long x = 0;            // x => ... 00000000 00000000 00000000 00000000
+ *  setbits64_right(10, x) // x => ... 00000000 00000000 00000011 11111111 */
 #define setbits64_right(_bits, _number)   (_number |= ~(ONE >> _bits))
 
 /* Same as setbits64_right but clears bits (sets to zeroes) */
@@ -117,11 +136,9 @@
 /* Set `size' bits starting from an address given by `ptr' to ones.
  * Example:
  *  char a[4];
- *  memset(a,0,4);
- *    // => 00000000 00000000 00000000 00000000
- *  setbits(&a, 11);
- *    // => 11111111 11100000 00000000 00000000 */
-void setbits(void *ptr, size_t size) {
+ *  memset(a,0,4);    // => 00000000 00000000 00000000 00000000
+ *  setbits(&a, 11);  // => 11111111 11100000 00000000 00000000 */
+static inline void setbits(size_t size, void *ptr) {
   size_t i;
   int64_t *lp = (int64_t*)ptr;
   for (i = 0; i < size/64; i++)
@@ -130,7 +147,7 @@ void setbits(void *ptr, size_t size) {
 }
 
 /* Same as `setbits' but clear the bits (set to zeroes). */
-void clearbits(void *ptr, size_t size) {
+static inline void clearbits(size_t size, void *ptr) {
   size_t i;
   int64_t *lp = (int64_t*)ptr;
   for (i = 0; i < size/64; i++)
@@ -138,14 +155,23 @@ void clearbits(void *ptr, size_t size) {
   clearbits64(size%64, *(lp+i));
 }
 
+/* Same as `setbits' but clear the bits (set to zeroes). */
+static inline int checkbits(size_t size, void *ptr) {
+  size_t i;
+  int64_t *lp = (int64_t*)ptr;
+  for (i = 0; i < size/64; i++) {
+    if (*(lp+i) != ONE)
+      return 0;
+  }
+  return checkbits64(size%64, *(lp+i));
+}
+
 /* Same as `setbits' but set the bits from right to left
  * Example:
  *  char a[4];
- *  memset(a,0,4);
- *    // => 00000000 00000000 00000000 00000000
- *  setbits_right(&a, 11);
- *    // => 00000000 00000000 00000111 11111111 */
-void setbits_right(void *ptr, size_t size) {
+ *  memset(a,0,4);         // => 00000000 00000000 00000000 00000000
+ *  setbits_right(&a, 11); // => 00000000 00000000 00000111 11111111 */
+static inline void setbits_right(size_t size, void *ptr) {
   size_t i = 0;
   int64_t *lp = (int64_t*)ptr - 1;
   for (i = 0; i < size/64; i++)
@@ -154,7 +180,7 @@ void setbits_right(void *ptr, size_t size) {
 }
 
 /* Same as `setbits_right' but clear the bits (set to zeroes). */
-void clearbits_right(void *ptr, size_t size) {
+static inline void clearbits_right(size_t size, void *ptr) {
   size_t i = 0;
   int64_t *lp = (int64_t*)ptr - 1;
   for (i = 0; i < size/64; i++)
@@ -162,4 +188,4 @@ void clearbits_right(void *ptr, size_t size) {
   clearbits64_right(size%64, *(lp-i));
 }
 /* }}} */
-#endif
\ No newline at end of file
+#endif
diff --git a/src/plugins/e-acsl/share/e-acsl/e_acsl_debug.h b/src/plugins/e-acsl/share/e-acsl/e_acsl_debug.h
index 8d2de060598d325b8a9516c9d24801ddb6a2b8ce..e41d7c1fa3053be47555dee6f42a7d309c329ece 100644
--- a/src/plugins/e-acsl/share/e-acsl/e_acsl_debug.h
+++ b/src/plugins/e-acsl/share/e-acsl/e_acsl_debug.h
@@ -25,6 +25,8 @@
  * \brief  Debug-level functions and macros
 ***************************************************************************/
 
+static void vabort(char *fmt, ...);
+
 /* Stringification macros {{{ */
 #ifndef E_ACSL_STRINGIFICATION
 #define E_ACSL_STRINGIFICATION
@@ -40,7 +42,7 @@
 
 /* Default location of the E_ACSL log file */
 #ifndef E_ACSL_DEBUG_LOG
-#  define E_ACSL_DEBUG_LOG /tmp/e-acsl.log
+#  define E_ACSL_DEBUG_LOG -
 #endif
 
 /*! \brief Name of the debug log file */
@@ -62,14 +64,13 @@ static int dlog_fd = -1;
  *  - open file descriptor
  *  - add program arguments to the log */
 static void initialize_report_file(int *argc, char ***argv) {
-  // Redirect the log to stderr is just set to be defined or set to '-'
+  /* Redirect the log to stderr is just set to be defined or set to '-' */
   if (!strcmp(dlog_name, "-") || !strcmp(dlog_name, "1")) {
     dlog_fd = 2;
   } else {
     dlog_fd = open(dlog_name, O_WRONLY | O_CREAT | O_TRUNC  |O_NONBLOCK
       | O_NOCTTY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
   }
-
   if (dlog_fd == -1)
     vabort("Cannot open file descriptor for %s\n", dlog_name);
   else {
@@ -89,13 +90,14 @@ static void initialize_report_file(int *argc, char ***argv) {
 static int debug_stop_number = 0;
 int getchar(void);
 
-#define STOP { \
-  DLOG(" << ==================== " "Debug Stop Point %d in '%s' at %s:%d" \
-    " ==================== >> ", \
+#define DSTOP { \
+  printf(" << ***** " "Debug Stop %d in '%s' at %s:%d" " ***** >> ", \
     ++debug_stop_number, __func__, __FILE__, __LINE__); \
-    getchar(); \
+  getchar(); \
 }
+
 #else
+#  define DSTOP
 #  define initialize_report_file(...)
 #  define DLOG(...)
 #  define DASSERT(_e)
diff --git a/src/plugins/e-acsl/share/e-acsl/e_acsl_mmodel.c b/src/plugins/e-acsl/share/e-acsl/e_acsl_mmodel.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e437e4f4561972999916dc78ed0d0c9a32111bd
--- /dev/null
+++ b/src/plugins/e-acsl/share/e-acsl/e_acsl_mmodel.c
@@ -0,0 +1,68 @@
+/**************************************************************************/
+/*                                                                        */
+/*  This file is part of the Frama-C's E-ACSL plug-in.                    */
+/*                                                                        */
+/*  Copyright (C) 2012-2015                                               */
+/*    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 license/LGPLv2.1).             */
+/*                                                                        */
+/**************************************************************************/
+
+/*! ***********************************************************************
+ * \file  e_acsl_memory_mmodel.c
+ * \brief Configuration macros and RTL assembly
+***************************************************************************/
+
+#include <sys/mman.h>
+#include <errno.h>
+#include <sys/resource.h>
+
+#include "e_acsl_string.h"
+#include "e_acsl_bits.h"
+#include "e_acsl_printf.h"
+#include "e_acsl_debug.h"
+#include "e_acsl_assert.h"
+#include "e_acsl_malloc.h"
+#include "e_acsl_safe_locations.h"
+
+/*    Memory model:
+ *      E_ACSL_BITTREE_MMODEL - use Patricia-trie (tree-based) memory model, or
+ *      E_ACSL_SEGMENT_MMODEL - use segment-based (shadow) memory model
+ *    Debug Features:
+ *      E_ACSL_DEBUG - enable debug features in RTL
+ *    Extra messages:
+ *      E_ACSL_IDENTIFY - print a message showing run configuration
+*/
+
+/* Print basic configuration before each run */
+static void identify_run() {
+#ifdef  E_ACSL_IDENTIFY
+  printf("/* ========================================================= */\n");
+  printf(" * E-ACSL instrumented run with: "
+#ifndef E_ACSL_DEBUG
+  "NO-"
+#endif
+  "DEBUG\n");
+  printf("/* ========================================================= */\n");
+#endif
+}
+
+#if defined E_ACSL_SEGMENT_MMODEL
+#  include "segment_model/e_acsl_segment_mmodel.c"
+#elif defined E_ACSL_BITTREE_MMODEL
+#  include "bittree_model/e_acsl_bittree_mmodel.c"
+#else
+#  error "No EACSL memory model defined. Aborting compilation"
+#endif
diff --git a/src/plugins/e-acsl/share/e-acsl/e_acsl_mmodel_api.h b/src/plugins/e-acsl/share/e-acsl/e_acsl_mmodel_api.h
index f19c4294999fd8276c77caa25075c4e87785026a..52351c9447bd3992d652ef49f156b8827d6abe2a 100644
--- a/src/plugins/e-acsl/share/e-acsl/e_acsl_mmodel_api.h
+++ b/src/plugins/e-acsl/share/e-acsl/e_acsl_mmodel_api.h
@@ -112,7 +112,7 @@ void __e_acsl_full_init(void * ptr)
 /*! \brief Mark a memory block which start address is given by \p ptr as
  * read-only. */
 /*@ assigns \nothing; */
-void __e_acsl_readonly(void * ptr)
+void __e_acsl_mark_readonly(void * ptr)
   __attribute__((FC_BUILTIN));
 
 /* ****************** */
@@ -134,7 +134,7 @@ int __e_acsl_freeable(void * ptr)
 /*@ ensures \result == 0 || \result == 1;
   @ ensures \result == 1 ==> \valid(((char *)ptr)+(0..size-1));
   @ assigns \result \from *(((char*)ptr)+(0..size-1)); */
-int __e_acsl_valid(void * ptr, size_t size)
+int __e_acsl_valid(void * ptr, size_t size, void *ptr_base, void *addr_of_base)
   __attribute__((FC_BUILTIN));
 
 /*! \brief Implementation of the \b \\valid_read predicate of E-ACSL.
@@ -144,7 +144,7 @@ int __e_acsl_valid(void * ptr, size_t size)
 /*@ ensures \result == 0 || \result == 1;
   @ ensures \result == 1 ==> \valid_read(((char *)ptr)+(0..size-1));
   @ assigns \result \from *(((char*)ptr)+(0..size-1)); */
-int __e_acsl_valid_read(void * ptr, size_t size)
+int __e_acsl_valid_read(void * ptr, size_t size, void *ptr_base, void *addr_of_base)
   __attribute__((FC_BUILTIN));
 
 /*! \brief Implementation of the \b \\base_addr predicate of E-ACSL.
@@ -206,8 +206,7 @@ void __e_acsl_memory_init(int *argc_ref, char ***argv, size_t ptr_size)
 size_t __e_acsl_get_heap_allocation_size(void)
   __attribute__((FC_BUILTIN));
 
-/*! \brief A variable holding a cumulative size (in bytes) of tracked
- * heap allocation. */
+/*! \brief A variable holding a byte size of tracked heap allocation. */
 extern size_t __e_acsl_heap_allocation_size;
 
 /*@ predicate diffSize{L1,L2}(integer i) =
diff --git a/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_mmodel.c b/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_mmodel.c
index 4699f2d81716064a64b8dc1578e6783eb36080dc..d5db5b65f366472ee1e70c6a9a16e4945e0f351d 100644
--- a/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_mmodel.c
+++ b/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_mmodel.c
@@ -26,21 +26,10 @@
  *   model. See e_acsl_mmodel_api.h for details.
 ***************************************************************************/
 
-#include <sys/mman.h>
-#include <errno.h>
-#include <sys/resource.h>
-
-static int valid(void * ptr, size_t size);
-static int valid_read(void * ptr, size_t size);
-
-#include "e_acsl_string.h"
-#include "e_acsl_bits.h"
-#include "e_acsl_printf.h"
-#include "e_acsl_assert.h"
-#include "e_acsl_debug.h"
-#include "e_acsl_malloc.h"
+static int valid(void*, size_t, void*, void*);
+static int valid_read(void*, size_t, void*, void*);
+
 #include "e_acsl_shadow_layout.h"
-#include "e_acsl_safe_locations.h"
 #include "e_acsl_segment_tracking.h"
 #include "e_acsl_mmodel_api.h"
 
@@ -59,7 +48,7 @@ static void delete_block(void * ptr) {
 }
 
 static void * store_block_duplicate(void * ptr, size_t size) {
-  if (valid_read(ptr, size))
+  if (allocated((uintptr_t)ptr, size, (uintptr_t)ptr))
     delete_block(ptr);
   shadow_alloca(ptr, size);
   return ptr;
@@ -69,35 +58,26 @@ static void full_init(void * ptr) {
   initialize(ptr, block_length(ptr));
 }
 
-static void readonly(void * ptr) {
-  mark_readonly((uintptr_t)ptr, block_length(ptr));
+static void mark_readonly(void * ptr) {
+  mark_readonly_region((uintptr_t)ptr, block_length(ptr));
 }
 
 /* ****************** */
 /* E-ACSL annotations */
 /* ****************** */
 
-static int valid(void * ptr, size_t size) {
+/** \brief Return 1 if a given memory location is read-only and 0 otherwise */
+static int readonly (void *ptr) {
   uintptr_t addr = (uintptr_t)ptr;
-  if (IS_ON_HEAP(addr))
-    return heap_allocated(addr, size);
-  else if (IS_ON_STACK(addr) || IS_ON_TLS(addr))
-    return static_allocated(addr, size);
-  else if (IS_ON_GLOBAL(addr))
-    return static_allocated(addr, size) && !global_readonly(addr);
-  else if (!IS_ON_VALID(addr))
-    return 0;
-  return 0;
+  return IS_ON_GLOBAL(addr) && global_readonly(addr) ? 1 : 0;
 }
 
-static int valid_read(void * ptr, size_t size) {
-  uintptr_t addr = (uintptr_t)ptr;
-  TRY_SEGMENT(addr,
-    return heap_allocated(addr, size),
-    return static_allocated(addr, size));
-  if (!IS_ON_VALID(addr))
-    return 0;
-  return 0;
+static int valid(void * ptr, size_t size, void *ptr_base, void *addr_of_base) {
+  return allocated((uintptr_t)ptr, size, (uintptr_t)ptr_base) && !readonly(ptr);
+}
+
+static int valid_read(void * ptr, size_t size, void *ptr_base, void *addr_of_base) {
+  return allocated((uintptr_t)ptr, size, (uintptr_t)ptr_base);
 }
 
 /*! NB: The implementation for this function can also be specified via
@@ -112,7 +92,7 @@ static void * segment_base_addr(void * ptr) {
 
 /*! NB: Implementation of the following function can also be specified
  * via \p block_length macro. A more direct approach via ::TRY_SEGMENT
- * is preffered for performance reasons. */
+ * is preferred for performance reasons. */
 static size_t segment_block_length(void * ptr) {
   TRY_SEGMENT(ptr,
     return heap_info((uintptr_t)ptr, 'L'),
@@ -122,7 +102,7 @@ static size_t segment_block_length(void * ptr) {
 
 /*! NB: Implementation of the following function can also be specified
  * via \p offset macro. A more direct approach via ::TRY_SEGMENT
- * is preffered for performance reasons. */
+ * is preferred for performance reasons. */
 static int segment_offset(void *ptr) {
   TRY_SEGMENT(ptr,
     return heap_info((uintptr_t)ptr, 'O'),
@@ -151,10 +131,9 @@ static void memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) {
   initialize_report_file(argc_ref, argv_ref);
   /* Lift stack limit to account for extra stack memory overhead.  */
   increase_stack_limit(get_stack_size()*2);
-  /* Allocate and log shadow memory layout of the execution. */
+  /* Allocate and log shadow memory layout of the execution */
   init_memory_layout(argc_ref, argv_ref);
-  /* Make sure the layout holds and output it (only in debug mode) */
-  DEBUG_PRINT_LAYOUT;
+  /* Make sure the layout holds */
   DVALIDATE_SHADOW_LAYOUT;
   /* Track program arguments. */
   if (argc_ref && argv_ref)
@@ -163,7 +142,6 @@ static void memory_init(int *argc_ref, char *** argv_ref, size_t ptr_size) {
   collect_safe_locations();
   int i;
   for (i = 0; i < safe_location_counter; i++) {
-    DLOG("Safe location %lu\n", safe_locations[i].address, safe_locations[i].address + safe_locations[i].length);
     void *addr = (void*)safe_locations[i].address;
     uintptr_t len = safe_locations[i].length;
     shadow_alloca(addr, len);
@@ -197,8 +175,8 @@ public_alias(valid_read)
 public_alias(valid)
 public_alias(initialized)
 public_alias(freeable)
-public_alias(readonly)
 /* Block initialization  */
+public_alias(mark_readonly)
 public_alias(initialize)
 public_alias(full_init)
 /* Memory state initialization */
diff --git a/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_tracking.h b/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_tracking.h
index ae8d30bfa8bf158d55a5ec3279c764b55aee3aa7..5c42f259ca2aeaebdb89e8e95f11408b8254a9d1 100644
--- a/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_tracking.h
+++ b/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_segment_tracking.h
@@ -27,6 +27,28 @@
 
 /* Segment settings and shadow values interpretation {{{ */
 
+/* This file implements segment-based and offset-based shadow memory models
+ * (shadow encodings) (see draft of the PLDI'17 paper).
+ *
+ * IMPORTANT: While the implementation of the offset-based encoding mostly
+ * follows the description given by the paper, there are differences in the
+ * segment-based encoding for tracking heap memory. Some of these differences
+ * are as follows:
+ *  1) Size of a heap segment is increased to 32 bytes
+ *  2) Heap meta-segments are no longer used, segment-based representation of
+ *    a heap block considers only block segments, such that:
+ *    - Lowest `intptr_t` bytes of each shadow segment tracking an application
+ *      block store the base address of that block;
+ *    - `intptr_t` bytes of the first segment following the initial `intptr_t`
+ *      bytes store the length of the block. Note, the length is only stored
+ *      by the first segment.
+ *  3) Per-byte initialization of application bytes is tracked via a disjoint
+ *    shadow region, which maps one bit of shadow memory to a byte of
+ *    application memory. Comments within this file often refer to a shadow
+ *    region tracking application blocks by segments as to `block shadow`,
+ *    and to the region tracking initialization as to `init shadow`.
+*/
+
 /*! @brief Byte size of a heap segment.
  * This size is potentially used as an argument to `memalign`.
  * It SHOULD be a multiple of 2 and a multiple of a pointer size.
@@ -35,10 +57,7 @@
  * size greater than 64 bytes. This is because presently some initialization
  * functionality relies on the fact that initialization per segment can be set
  * and/or evaluated using an 8-byte bitmask. */
-#define HEAP_SEGMENT 16
-
-/*! \brief Number of bytes required to represent initialization of a segment. */
-#define INIT_BYTES (HEAP_SEGMENT/8)
+#define HEAP_SEGMENT 32
 
 /*! \brief Size (in bytes) of a long block on the stack. */
 #define LONG_BLOCK 8
@@ -79,26 +98,30 @@
  * offset at which to read meta-data is (51 - 48). */
 #define LONG_BLOCK_INDEX_START 48
 
-/*! \brief Increase the size to a multiple of a segment size. */
-#define ALIGNED_SIZE(_s) \
-  (_s + ((_s%HEAP_SEGMENT) ? (HEAP_SEGMENT - _s%HEAP_SEGMENT) : 0))
+/*! \brief  Decrease _n to be a multiple of _m */
+#define ALIGN_LEFT(_n, _m) (_n - _n%_m)
 
-/*! \brief Given the size of a block return the number of segments
- * that represent that block in the heap shadow */
-#define BLOCK_SEGMENTS(_s) (ALIGNED_SIZE(_s)/HEAP_SEGMENT)
+/*! \brief  Increase _n to be a multiple of _m */
+#define ALIGN_RIGHT(_n, _m) (_n + ((_n%_m) ? (_m - _n%_m) : 0))
+
+/*! \brief Heap shadow address aligned at a segment boundary */
+#define ALIGNED_HEAP_SHADOW(_addr) \
+  HEAP_SHADOW(ALIGN_LEFT(_addr,HEAP_SEGMENT))
 
 /* \brief Maximal size_t value that does not cause overflow via addition
  * when segment size is added. */
-const size_t max_allocated = SIZE_MAX - HEAP_SEGMENT;
+static const size_t max_allocated = ALIGN_LEFT(SIZE_MAX,HEAP_SEGMENT);
 
-/* \brief Return actual allocation size which takes into account meta-block.
- * In the present implementation it is the requested size of a heap block +
- * the size if a segment */
-#define ALLOC_SIZE(_s) (_s > 0 && _s < max_allocated ? _s + HEAP_SEGMENT : 0)
+/* \brief Return actual allocation size which takes into account aligned
+ * allocation. In the present implementation it is the requested size of
+ * a heap block aligned at a segment boundary */
+#define ALLOC_SIZE(_s) \
+  (_s < max_allocated ? ALIGN_RIGHT(_s,	HEAP_SEGMENT) : 0)
 
-/*! \brief The number of bytes used to represent a heap block in its shadow.
- * In the current implementation it aligned size + meta-segment size */
-#define HEAP_SHADOW_BLOCK_SIZE(_s) ((BLOCK_SEGMENTS(_s) + 1)*HEAP_SEGMENT)
+/** \brief Evaluate to `true` if address _addr belongs to a memory block
+ * with base address _base and length _length */
+#define BELONGS(_addr, _base, _length) \
+  (_addr >= _base && _addr < _base + _length)
 
 /*! \brief For short blocks numbers 1 to 36 represent lengths and offsets,
  * such that:
@@ -157,15 +180,15 @@ static const uint64_t heap_init_mask = ~(ONE << HEAP_SEGMENT);
  * For instance, mark first X bytes of a number N as initialised:
  *    N |= static_init_masks[X] */
 static const uint64_t static_init_masks [] = {
-  0UL, /* 0 bytes */
-  1UL,  /* 1 byte */
-  257UL,  /* 2 bytes */
-  65793UL,  /* 3 bytes */
-  16843009UL,  /* 4 bytes */
-  4311810305UL,  /* 5 bytes */
-  1103823438081UL,  /* 6 bytes */
-  282578800148737UL,	/* 7 bytes */
-  72340172838076673UL		/* 8 bytes */
+  0, /* 0 bytes */
+  1,  /* 1 byte */
+  257,  /* 2 bytes */
+  65793,  /* 3 bytes */
+  16843009,  /* 4 bytes */
+  4311810305,  /* 5 bytes */
+  1103823438081,  /* 6 bytes */
+  282578800148737,	/* 7 bytes */
+  72340172838076673		/* 8 bytes */
 };
 
 /*! \brief Bit masks for setting read-only (second least significant) bits.
@@ -182,15 +205,15 @@ static const uint64_t static_init_masks [] = {
  *  For instance, mark first X bytes of a number N as read-only:
  *    N |= static_readonly_masks[X] */
 static const uint64_t static_readonly_masks [] = {
-  0UL, /* 0 bytes */
-  2UL, /* 1 byte */
-  514UL, /* 2 bytes */
-  131586UL, /* 3 bytes */
-  33686018UL, /* 4 bytes */
-  8623620610UL, /* 5 bytes */
-  2207646876162UL, /* 6 bytes */
-  565157600297474UL, /* 7 bytes */
-  144680345676153346UL /* 8 bytes */
+  0, /* 0 bytes */
+  2, /* 1 byte */
+  514, /* 2 bytes */
+  131586, /* 3 bytes */
+  33686018, /* 4 bytes */
+  8623620610, /* 5 bytes */
+  2207646876162, /* 6 bytes */
+  565157600297474, /* 7 bytes */
+  144680345676153346 /* 8 bytes */
 };
 /* }}} */
 
@@ -206,7 +229,7 @@ static void validate_memory_layout() {
   /* Check that the struct holding memory layout is marked as initialized. */
   DVASSERT(mem_layout.initialized != 0, "Un-initialized shadow layout", NULL);
   /* Make sure the order of program segments is as expected, i.e.,
-   * top to bittom: stack -> tls -> heap -> global*/
+   * top to bottom: stack -> tls -> heap -> global */
 
   #define NO_MEM_SEGMENTS 11
   uintptr_t segments[NO_MEM_SEGMENTS][2] = {
@@ -273,31 +296,83 @@ static void validate_memory_layout() {
 #define DVALIDATE_IS_ON_STATIC(_addr, _size) \
   DVALIDATE_IS_ON(_addr, _size, STATIC)
 
+/* Assert that `_addr` is on heap and it is the base address of an allocated
+ * heap memory block */
+#define DVALIDATE_FREEABLE(_addr) \
+  DVASSERT(IS_ON_HEAP(_addr), "Expected heap location: %a\n", _addr); \
+  DVASSERT(_addr == base_addr(_addr), \
+      "Expected base address, i.e., %a, not %a\n", base_addr(_addr), _addr);
+
 /* Assert that a memory block [_addr, _addr + _size] is allocated on a
  * program's heap */
 # define DVALIDATE_HEAP_ACCESS(_addr, _size) \
-    DVASSERT(IS_ON_HEAP(_addr), "Expected heap location: %a\n   ", _addr); \
-    DVASSERT(heap_allocated((uintptr_t)_addr, _size), \
-       "Operation on unallocated heap block [%a + %lu]\n   ",  _addr, _size)
+    DVASSERT(IS_ON_HEAP(_addr), "Expected heap location: %a\n", _addr); \
+    DVASSERT(heap_allocated((uintptr_t)_addr, _size, (uintptr_t)_addr), \
+       "Operation on unallocated heap block [%a + %lu]\n",  _addr, _size)
+
+/* Assert that every location belonging to the range [_addr, _addr + _size] is
+ * - belongs to a tracked static region (i.e., stack, TLS or global)
+ * - not allocated */
+# define DVALIDATE_HEAP_FREE(_addr, _size) { \
+  uintptr_t i, a = (uintptr_t)_addr; \
+  for (i = 0; i < _size; i++) { \
+    DVASSERT(IS_ON_HEAP(a + i), "Expected heap location: %a\n", a + i); \
+    DVASSERT(!heap_allocated(a + i, 1, a + i), \
+      "Expected heap unallocated location: [%a + %lu]\n", a, i); \
+  } \
+}
 
 /* Assert that memory block [_addr, _addr + _size] is allocated on stack, TLS
  * or globally */
 # define DVALIDATE_STATIC_ACCESS(_addr, _size) \
-    DVASSERT(IS_ON_STATIC(_addr), "Expected location: %a\n   ", _addr); \
-    DVASSERT(static_allocated((uintptr_t)_addr, _size), \
-       "Operation on unallocated block [%a + %lu]\n   ", _addr, _size)
+    DVASSERT(IS_ON_STATIC(_addr), \
+        "Expected static location: [%a + %lu], \n", _addr, _size); \
+    DVASSERT(static_allocated((uintptr_t)_addr, _size,(uintptr_t)_addr), \
+       "Operation on unallocated static block [%a + %lu]\n", _addr, _size)
 
 /* Same as ::DVALIDATE_STATIC_LOCATION but for a single memory location */
 # define DVALIDATE_STATIC_LOCATION(_addr) \
-    DVASSERT(IS_ON_STATIC(_addr), "Expected location: %a\n   ", _addr); \
+    DVASSERT(IS_ON_STATIC(_addr), \
+      "Expected static location: %a\n", _addr); \
     DVASSERT(static_allocated_one((uintptr_t)_addr), \
-       "Operation on unallocated block [%a]\n   ", _addr)
+      "Operation on unallocated static block [%a]\n", _addr)
+
+/* Assert that every location belonging to the range [_addr, _addr + _size] is
+ * - belongs to a tracked static region (i.e., stack, TLS or global)
+ * - not allocated */
+# define DVALIDATE_STATIC_FREE(_addr, _size) { \
+  uintptr_t i, a = (uintptr_t)_addr; \
+  for (i = 0; i < _size; i++) { \
+    DVASSERT(IS_ON_STATIC(a + i), \
+      "Expected static location in freea: %a\n", a + i); \
+    DVASSERT(!static_allocated_one(a + i), \
+      "Expected static unallocated location in freea: [%a + %lu]\n", a, i); \
+  } \
+}
 
-/* Assert that a memory block [_addr, _adddr + _size] is nullified */
+/* Assert that a memory block [_addr, _addr + _size] is nullified */
 # define DVALIDATE_NULLIFIED(_addr, _size) \
   DVASSERT(zeroed_out((void *)_addr, _size), \
     "Block [%a, %a+%lu] not nullified", _addr, _addr, _size)
 
+/* Assert that memory block [_addr, _addr + _size] is allocated */
+# define DVALIDATE_ALLOCATED(_addr, _size, _base) \
+  DVASSERT(allocated((uintptr_t)_addr, _size, (uintptr_t)_base), \
+    "Operation on unallocated block [%a + %lu] with base %a\n", \
+    _addr, _size, _base)
+
+/* Assert that memory block [_addr, _addr + _size] is allocated
+ * and can be written to */
+# define DVALIDATE_RW_ACCESS(_addr, _size) { \
+  DVALIDATE_ALLOCATED((uintptr_t)_addr, _size, (uintptr_t)_addr); \
+  DVASSERT(!readonly((void*)_addr), \
+    "Unexpected readonly address: %lu\n", _addr) \
+}
+
+/* Assert that memory block [_addr, _addr + _size] is allocated */
+# define DVALIDATE_RO_ACCESS(_addr, _size) \
+  DVALIDATE_ALLOCATED((uintptr_t)_addr, _size, (uintptr_t)_addr)
+
 #else
 /*! \cond exclude from doxygen */
 #  define DVALIDATE_SHADOW_LAYOUT
@@ -312,6 +387,12 @@ static void validate_memory_layout() {
 #  define DVALIDATE_IS_ON_GLOBAL
 #  define DVALIDATE_IS_ON_TLS
 #  define DVALIDATE_IS_ON_STATIC
+#  define DVALIDATE_FREEABLE
+#  define DVALIDATE_STATIC_FREE
+#  define DVALIDATE_HEAP_FREE
+#  define DVALIDATE_RO_ACCESS
+#  define DVALIDATE_RW_ACCESS
+#	 define DVALIDATE_ALLOCATED
 /*! \endcond */
 #endif
 /* }}} */
@@ -320,27 +401,16 @@ static void validate_memory_layout() {
 /* See definitions for documentation */
 static uintptr_t heap_info(uintptr_t addr, char type);
 static uintptr_t static_info(uintptr_t addr, char type);
-static int heap_allocated(uintptr_t addr, size_t size);
-static int static_allocated(uintptr_t addr, long size);
+static int heap_allocated(uintptr_t addr, size_t size, uintptr_t base_ptr);
+static int static_allocated(uintptr_t addr, long size, uintptr_t base_ptr);
+static int allocated(uintptr_t addr, long size, uintptr_t base_ptr);
 static int freeable(void *ptr);
 
 /*! \brief Quick test to check if a static location belongs to allocation.
  * This macro really belongs where static_allocated is defined, but
  * since it is used across this whole file it needs to be defined here. */
-#define static_allocated_one(addr) \
-  ((int)PRIMARY_SHADOW(addr))
-
-/*! \brief Shortcut for executing statements based on the segment a given
- * address belongs to.
- * \param intptr_t _addr - a memory address
- * \param code_block _heap_stmt - code executed if `_addr` is a heap address
- * \param code_block _static_stmt - code executed if `_addr` is a static address */
-#define TRY_SEGMENT_WEAK(_addr, _heap_stmt, _static_stmt)  \
-  if (IS_ON_HEAP(_addr)) { \
-    _heap_stmt; \
-  } else if (IS_ON_STATIC(_addr)) { \
-    _static_stmt; \
-  } \
+#define static_allocated_one(_addr) \
+  (*((unsigned char*)PRIMARY_SHADOW(_addr)))
 
 /*! \brief Shortcut for executing statements based on the segment a given
  * address belongs to.
@@ -352,7 +422,7 @@ static int freeable(void *ptr);
     _heap_stmt; \
   } else if (IS_ON_STATIC(_addr)) { \
     _static_stmt; \
-  } \
+  }
 
 /*! \brief Same as TRY_SEGMENT but performs additional checks aborting the
  * execution if the given address is `NULL` or does not belong to known
@@ -363,10 +433,8 @@ static int freeable(void *ptr);
  * the given address does not belong to any of the known segments. */
 #define TRY_SEGMENT(_addr, _heap_stmt, _static_stmt) { \
   TRY_SEGMENT_WEAK(_addr, _heap_stmt, _static_stmt) \
-  else if (_addr == 0) { \
-    vassert(0, "Unexpected null pointer\n", NULL); \
-  } else { \
-    vassert(0, "Address %a not found in known segments\n", _addr); \
+  else { \
+    vassert(0, "Use of invalid address %a in %s\n", _addr, __func__); \
   } \
 }
 
@@ -385,15 +453,11 @@ static uintptr_t predicate(uintptr_t addr, char p) {
   return 0;
 }
 
-/*! \brief Return a byte length of a memory block address `_addr` belongs to
- * \param uintptr_t _addr - a memory address */
+/*! \brief Return the byte length of the memory block containing `_addr` */
 #define block_length(_addr) predicate((uintptr_t)_addr, 'L')
-/*! \brief Return a base address of a memory block address `_addr` belongs to
- * \param uintptr_t _addr - a memory address */
+/*! \brief Return the base address of the memory block containing `_addr` */
 #define base_addr(_addr) predicate((uintptr_t)_addr, 'B')
-/*! \brief Return a byte offset of a memory address given by `_addr` within
- * its block
- * \param uintptr_t _addr - a memory address */
+/*! \brief Return the byte offset of `_addr` within its block */
 #define offset(_addr) predicate((uintptr_t)_addr, 'O')
 /* }}} */
 
@@ -434,7 +498,7 @@ static void shadow_alloca(void *ptr, size_t size) {
   uint64_t *prim_shadow_alt = (uint64_t *)PRIMARY_SHADOW(ptr);
   unsigned int *sec_shadow = (unsigned int*)SECONDARY_SHADOW(ptr);
 
-  /* Make sure static region is nullified */
+  /* Make sure shadows are nullified */
   DVALIDATE_NULLIFIED(prim_shadow, size);
   DVALIDATE_NULLIFIED(sec_shadow, size);
 
@@ -488,8 +552,10 @@ static void shadow_freea(void *ptr) {
 /*! \brief Return a non-zero value if a memory region of length `size`
  * starting at address `addr` belongs to a tracked stack, tls or
  * global memory block and 0 otherwise.
- * This function is only safe if applied to a tls, stack or global address. */
-static int static_allocated(uintptr_t addr, long size) {
+ * This function is only safe if applied to a tls, stack or global address.
+ * Explanations regarding the third argument - `base_ptr` - are given
+ * via inline documentation of function ::heap_allocated */
+static int static_allocated(uintptr_t addr, long size, uintptr_t base_ptr) {
   unsigned char *prim_shadow = (unsigned char*)PRIMARY_SHADOW(addr);
   /* Unless the address belongs to tracked allocation 0 is returned */
   if (prim_shadow[0]) {
@@ -506,7 +572,14 @@ static int static_allocated(uintptr_t addr, long size) {
       offset = short_offsets[code];
       length = short_lengths[code];
     }
-    return offset + size <= length;
+
+    if (addr != base_ptr) {
+      uintptr_t base_addr = addr - offset;
+      return BELONGS(base_ptr, base_addr, length)
+        && offset + size <= length;
+    } else {
+      return offset + size <= length;
+    }
   }
   return 0;
 }
@@ -517,7 +590,7 @@ static int static_allocated(uintptr_t addr, long size) {
 static int static_initialized(uintptr_t addr, long size) {
   /* Return 0 right away if the address does not belong to
    * static allocation */
-  if (!static_allocated(addr, size))
+  if (!static_allocated(addr, size, addr))
     return 0;
   DVALIDATE_STATIC_ACCESS(addr, size);
 
@@ -555,9 +628,9 @@ static int static_initialized(uintptr_t addr, long size) {
  * - 'L' - return the size in bytes of the memory block `addr` belongs to or `0`
  *     if `addr` lies outside of tracked allocation.
  *
- * NB: One should make sure that a given address if valid before querying.
- * That is, for the cases when addr does not refer to a valid memory address
- * belonging to static allocation the return value for this function is
+ * NB: One should make sure that a given address is allocated before querying.
+ * That is, for the cases when addr does not refer to an allocated memory
+ * address belonging to static allocation the return value for this function is
  * unspecified. */
 static uintptr_t static_info(uintptr_t addr, char type) {
   DVALIDATE_STATIC_LOCATION(addr);
@@ -646,11 +719,11 @@ static void initialize_static_region(uintptr_t addr, long size) {
  * NOTE: This function has many similarities with ::initialize_static_region
  * The functionality, however is preferred to be kept separate
  * because the ::mark_readonly should operate only on the global shadow. */
-static void mark_readonly (uintptr_t addr, long size) {
+static void mark_readonly_region (uintptr_t addr, long size) {
   /* Since read-only blocks can only be stored in the globals  segments (e.g.,
    * TEXT), this function required ptr carry a global address. */
   DASSERT(IS_ON_GLOBAL(addr));
-  DASSERT(static_allocated(addr, 1));
+  DASSERT(static_allocated_one(addr));
   DVASSERT(!(addr - base_addr(addr) + size > block_length(addr)),
     "Attempt to mark read-only %lu bytes past block boundaries\n"
     "starting at %a with block length %lu at base address %a\n",
@@ -691,56 +764,39 @@ static size_t heap_allocation_size = 0;
 /*! \brief Create a heap shadow for an allocated memory block starting at `ptr`
  * and of length `size`. Optionally mark it as initialized if `init`
  * evaluates to a non-zero value.
- * \b NOTE: This function assumes that `ptr` is a valid base address of a
+ * \b NOTE: This function assumes that `ptr` is a base address of a
  * heap-allocated memory block, such that HEAP_SEGMENT bytes preceding `ptr`
  * correspond to `unusable space`.
  * \b WARNING: Current implementation assumes that the size of a heap segment
  * does not exceed 64 bytes. */
-static void set_heap_segment(void *ptr, size_t size, size_t init) {
+static void set_heap_segment(void *ptr, size_t size, size_t alloc_size, size_t init) {
   /* Ensure the shadowed block in on the tracked heap portion */
   DVALIDATE_IS_ON_HEAP(((uintptr_t)ptr) - HEAP_SEGMENT, size);
   DVALIDATE_ALIGNMENT(ptr); /* Make sure alignment is right */
-  heap_allocation_size += size; /* Adjuct tracked allocation size */
+  heap_allocation_size += size; /* Adjust tracked allocation size */
 
   /* Get aligned size of the block, i.e., an actual size of the
    * allocated block */
-  size_t aligned_size = ALIGNED_SIZE(size);
-  unsigned char *shadowed = (unsigned char*)HEAP_SHADOW(ptr);
-  uintptr_t *shadow_meta = (uintptr_t*)(shadowed - HEAP_SEGMENT);
+  unsigned char *shadow = (unsigned char*)HEAP_SHADOW(ptr);
 
   /* Make sure shadow is nullified before setting it */
-  DVALIDATE_NULLIFIED(shadow_meta, aligned_size + HEAP_SEGMENT);
-
-  /* Write the actual length to the meta-segment. First 8 (or 4 in a 32-bit
-   * system) bytes of the segment are nullified to indicate that this segment
-   * does not correspond to an allocated memory block. The following block (at
-   * index 1) captures the size of the segment in bytes. */
-  shadow_meta[1] = size;
+  DVALIDATE_NULLIFIED(shadow, alloc_size);
 
   /* The overall number of block segments in a tracked memory block  */
-  size_t block_segments = aligned_size/HEAP_SEGMENT;
-  uintptr_t *block_segment = NULL;
-  int i;
+  size_t segments = alloc_size/HEAP_SEGMENT;
+  uintptr_t *segment = (uintptr_t*)(shadow);
+  segment[1] = size;
 
+  int i;
   /* Write the offsets per segment */
-  for (i = 0; i < block_segments; i++) {
-    block_segment = (uintptr_t*)(shadowed + i*HEAP_SEGMENT);
-    /* Write down the segment offset to the first 8 (or 4) bytes of the segment.
-     * Here it is necessary to increment the offset by one. If there is no
-     * increment, then the offset of the first segment is 0, which is the same
-     * as for a segment that does not belong to a program's allocation. */
-    *block_segment = i*HEAP_SEGMENT + 1;
+  for (i = 0; i < segments; i++) {
+    segment = (uintptr_t*)(shadow + i*HEAP_SEGMENT);
+    *segment = (uintptr_t)ptr;
   }
 
   /* If init is a non-zero value then mark all allocated bytes as initialized */
   if (init) {
-    for (i = 0; i < block_segments; i++) {
-      block_segment = (uintptr_t*)(shadowed + i*HEAP_SEGMENT);
-      block_segment[1] |= heap_init_mask;
-    }
-    /* If the last segment is partially allocated, nullify the unallocated
-     * bits back. */
-    block_segment[1] &= ~(ONE << size%HEAP_SEGMENT);
+    memset(HEAP_INIT_SHADOW(ptr), (unsigned int)ONE, alloc_size/8);
   }
 }
 
@@ -758,13 +814,13 @@ static void set_heap_segment(void *ptr, size_t size, size_t init) {
  *    returned pointer shall not be used to access an object." */
 static void* shadow_malloc(size_t size) {
   size_t alloc_size = ALLOC_SIZE(size);
+
   /* Return NULL if the size is too large to be aligned */
-  char* res = alloc_size ? (char*)native_malloc(alloc_size) : NULL;
+  char* res = alloc_size ?
+    (char*)native_aligned_alloc(HEAP_SEGMENT, alloc_size) : NULL;
 
-  if (res) {
-    res += HEAP_SEGMENT;
-    set_heap_segment(res, size, 0);
-  }
+  if (res)
+    set_heap_segment(res, size, alloc_size, 0);
 
   return res;
 }
@@ -774,17 +830,18 @@ static void* shadow_calloc(size_t nmemb, size_t size) {
   /* Since both `nmemb` and `size` are both of size `size_t` the multiplication
    * of the arguments (which gives the actual allocation size) might lead to an
    * integer overflow. The below code checks for an overflow and sets the
-   * `alloc_size` (agrument a memory allocation function) to zero. */
+   * `alloc_size` (argument a memory allocation function) to zero. */
   size = (size && nmemb > SIZE_MAX/size) ? 0 : nmemb*size;
 
+  size_t alloc_size = ALLOC_SIZE(size);
+
   /* Since aligned size is required by the model do the allocation through
    * `malloc` and nullify the memory space by hand */
-  char* res = size ? (char*)native_malloc(ALLOC_SIZE(size)) : NULL;
+  char* res = size ? (char*)native_malloc(alloc_size) : NULL;
 
   if (res) {
-    res += HEAP_SEGMENT;
     memset(res, 0, size);
-    set_heap_segment(res, size, 1);
+    set_heap_segment(res, size, alloc_size, 1);
   }
 
   return res;
@@ -792,16 +849,37 @@ static void* shadow_calloc(size_t nmemb, size_t size) {
 /* }}} */
 
 /* Heap deallocation (free) {{{ */
-static void shadow_free(void *res) {
-  char *ptr = (char *)res;
+
+/*! \brief Remove a memory block with base address given by `ptr` from tracking.
+ * This function effectively nullifies block shadow tracking an application
+ * block and optionally nullifies an init shadow associated with the block.
+ *
+ * NOTE: ::unset_heap_segment assumes that `ptr` is a base address of an
+ * allocated heap memory block, i.e., `freeable(ptr)` evaluates to true. */
+static void unset_heap_segment(void *ptr, int init) {
+  DVALIDATE_FREEABLE(((uintptr_t)ptr));
+  /* Base address of shadow block */
+  uintptr_t *base_shadow = (uintptr_t*)HEAP_SHADOW(ptr);
+  /* Physical allocation size */
+  size_t alloc_size = ALLOC_SIZE(base_shadow[1]);
+  /* Actual block length */
+  size_t length = base_shadow[1];
+  /* Nullify shadow block */
+  memset(base_shadow, ZERO, alloc_size);
+  /* Adjust tracked allocation size */
+  heap_allocation_size -= length;
+  /* Nullify init shadow */
+  if (init) {
+    memset(HEAP_INIT_SHADOW(ptr), 0, alloc_size/8);
+  }
+}
+
+/*! \brief Replacement for `free` with memory tracking  */
+static void shadow_free(void *ptr) {
   if (ptr != NULL) { /* NULL is a valid behaviour */
     if (freeable(ptr)) {
-      size_t size = block_length(ptr);
-      void *meta_shadow = (void*)(HEAP_SHADOW(ptr) - HEAP_SEGMENT);
-      memset(meta_shadow, 0, HEAP_SHADOW_BLOCK_SIZE(size));
-      native_free(ptr - HEAP_SEGMENT);
-      /* Adjuct tracked allocation size carried via `__e_acsl_heap_allocation_size` */
-      heap_allocation_size -= size;
+      unset_heap_segment(ptr, 1);
+      native_free(ptr);
     } else {
       vabort("Not a start of block (%a) in free\n", ptr);
     }
@@ -810,8 +888,7 @@ static void shadow_free(void *res) {
 /* }}} */
 
 /* Heap reallocation (realloc) {{{ */
-static void* shadow_realloc(void *p, size_t size) {
-  char *ptr = (char*)p;
+static void* shadow_realloc(void *ptr, size_t size) {
   char *res = NULL; /* Resulting pointer */
   /* If the pointer is NULL then realloc is equivalent to malloc(size) */
   if (ptr == NULL)
@@ -821,76 +898,45 @@ static void* shadow_realloc(void *p, size_t size) {
   else if (ptr != NULL && size == 0) {
     shadow_free(ptr);
   } else {
-    if (freeable(ptr)) { /* ... and valid for free  */
+    if (freeable(ptr)) { /* ... and can be used as an input to `free` */
       size_t alloc_size = ALLOC_SIZE(size);
-      res = native_realloc(ptr - HEAP_SEGMENT, alloc_size);
+      res = native_realloc(ptr, alloc_size);
       DVALIDATE_ALIGNMENT(res);
 
       /* realloc succeeds, otherwise nothing needs to be done */
       if (res != NULL) {
-        res += HEAP_SEGMENT;
-        /* Tracked size of the old allocation */
-        size_t old_size = block_length((uintptr_t)ptr);
-        /* Number of block segments in the old allocation */
-        size_t old_segments = BLOCK_SEGMENTS(old_size);
-        /* Number of block segments in the new allocation */
-        size_t new_segments = BLOCK_SEGMENTS(size);
-        /* Adjuct tracked allocation size */
-        heap_allocation_size += -old_size + size;
-
-        /* Address of the meta-block in old allocation */
-        uintptr_t *meta_shadow = (uintptr_t*)(HEAP_SHADOW(ptr) - HEAP_SEGMENT);
-
-        /* The case when realloc displaces the base address of a pointer */
-        if (ptr != res) {
-          /* Address of the new shadow meta-block */
-          uintptr_t *new_meta_shadow =
-            (uintptr_t*)(HEAP_SHADOW(res) - HEAP_SEGMENT);
-          size_t inflen = HEAP_SEGMENT*(old_segments + 1);
-          /* Copy information over to the new shadow ... */
-          memcpy(new_meta_shadow, meta_shadow, inflen);
-          /* ... and nuke the old shadow */
-          memset(meta_shadow, 0, inflen);
-          meta_shadow = new_meta_shadow;
+        size_t alloc_size = ALLOC_SIZE(size);
+        size_t old_size = block_length(ptr);
+        size_t old_alloc_size = ALLOC_SIZE(old_size);
+
+        /* Nullify old representation */
+        unset_heap_segment(ptr, 0);
+
+        /* Set up new block shadow */
+        set_heap_segment(res, size, alloc_size, 0);
+
+        /* Move init shadow */
+        unsigned char* old_init_shadow  = (unsigned char*)HEAP_INIT_SHADOW(ptr);
+        unsigned char* new_init_shadow  = (unsigned char*)HEAP_INIT_SHADOW(res);
+
+        /* If realloc truncates allocation in the old init shadow it is first
+         * needed to clear the old init shadow from the boundary of the old
+         * shadow block to the size of the new allocation */
+        if (old_size > size) {
+          clearbits_right(
+              old_alloc_size - size,
+              old_init_shadow + old_alloc_size/8);
         }
 
-        /* Set new size */
-        meta_shadow[1] = size;
-
-        /* Realloc truncates allocation, need to truncate the shadow as well:
-         *  1. Get the last segment in the new allocation and clear all init
-         *    bits from the old allocation that do not belong in the new.
-         *  2. Nullify segments tracking old allocation but which do not
-         *    belong to the new one. These will be past the last segment
-         *    (as above). */
-        if (old_segments > new_segments) {
-          /* Last segment in the new allocation and the number of bits to
-           * clear out */
-          size_t last_index = new_segments - 1;
-          size_t clear_bits = HEAP_SEGMENT - (size - last_index*HEAP_SEGMENT);
-
-          /* Reset initialization in shadow past the new allocation (1). */
-          void *seg_last = (void*)
-            (HEAP_SHADOW(res) +
-            last_index*HEAP_SEGMENT + INIT_BYTES + PTR_SZ);
-          clearbits_right(seg_last, clear_bits);
-
-          /* Clear out remaining shadow data from old allocation that is
-           * not used in the new allocation (2) */
-          int diff = old_segments - new_segments;
-          char *seg_next = (char*)(HEAP_SHADOW(res)
-            + (last_index+1)*HEAP_SEGMENT);
-          memset(seg_next, 0, diff*HEAP_SEGMENT);
-       /* Realloc increases allocation, only segment indices need to be added */
-        } else if (old_segments < new_segments) {
-          /* Just add indices to shadow. Realloc does not initialize
-           * allocated data past the old allocation. */
-          int i;
-          for (i = old_segments; i < new_segments; i++) {
-            uintptr_t *seg_next = (uintptr_t*)(HEAP_SHADOW(res)
-              + i*HEAP_SEGMENT);
-            seg_next[0] = HEAP_SEGMENT*i + 1;
-          }
+        /* Now init shadow can be moved (if needed), keep in mind that
+         * segment base addresses are aligned at a boundary of something
+         * divisible by 8, so instead of moving actual bits here the
+         * segments are moved to avoid dealing with bit-level operations
+         * on incomplete bytes. */
+        if (res != ptr) {
+          size_t copy_size = (old_size > size) ? alloc_size : old_alloc_size;
+          memcpy(new_init_shadow, old_init_shadow, copy_size);
+          memset(old_init_shadow, 0, copy_size);
         }
       }
     } else {
@@ -912,10 +958,9 @@ static void *shadow_aligned_alloc(size_t alignment, size_t size) {
     return NULL;
 
   char *res = native_aligned_alloc(alignment, size);
-  if (res) {
-    res += HEAP_SEGMENT;
-    set_heap_segment(res, size, 0);
-  }
+  if (res)
+    set_heap_segment(res, size, ALLOC_SIZE(size), 0);
+
   return (void*)res;
 }
 /* }}} */
@@ -930,13 +975,12 @@ static int shadow_posix_memalign(void **memptr, size_t alignment, size_t size) {
     return -1;
 
   /* Make sure that the first argument to posix memalign is indeed allocated */
-  vassert(valid(memptr, sizeof(void*)),
+  vassert(allocated((uintptr_t)memptr, sizeof(void*), (uintptr_t)memptr),
       "\\invalid memptr in  posix_memalign", NULL);
 
   int res = native_posix_memalign(memptr, alignment, size);
   if (!res) {
-    *memptr += HEAP_SEGMENT;
-    set_heap_segment(*memptr, size, 0);
+    set_heap_segment(*memptr, size, ALLOC_SIZE(size), 0);
   }
   return res;
 }
@@ -946,28 +990,36 @@ static int shadow_posix_memalign(void **memptr, size_t alignment, size_t size) {
 /*! \brief Return a non-zero value if a memory region of length `size`
  * starting at address `addr` belongs to an allocated (tracked) heap memory
  * block and a 0 otherwise. Note, this function is only safe if applied to a
- * heap address. */
-static int heap_allocated(uintptr_t addr, size_t size) {
-  /* Offset within the segment */
-  size_t block_offset = addr%HEAP_SEGMENT;
-  /* Address of the shadow segment the address belongs to */
-  uintptr_t *aligned_shadow =
-    (uintptr_t*)HEAP_SHADOW(addr - block_offset);
+ * heap address.
+ *
+ * Note the third argument `base_ptr` that represents the base of a pointer, i.e.,
+ * `addr` of the form `base_ptr + i`, where `i` is some integer index.
+ * ::heap_allocated also returns zero if `base_ptr` and `addr` belong to different
+ * memory blocks, or if `base_ptr` lies within unallocated region. The intention
+ * here is to be able to detect dereferencing of an allocated memory block through
+ * a pointer to a different block. Consider, for instance, some pointer `p` that
+ * points to a memory block `B`, and an index `i`, such that `p+i` references a
+ * memory location belonging to a different memory block (say `C`). From a
+ * low-level viewpoint, dereferencing `p+i` is safe (since it belongs to a properly
+ * allocated block). From our perspective, however, dereference of `p+i` is
+ * only legal if both `p` and `p+i` point to the same block. */
+static int heap_allocated(uintptr_t addr, size_t size, uintptr_t base_ptr) {
+  /* Base address of the shadow segment the address belongs to */
+  uintptr_t *shadow = (uintptr_t*)HEAP_SHADOW(addr - addr%HEAP_SEGMENT);
 
   /* Non-zero if the segment belongs to heap allocation */
-  if (aligned_shadow[0]) {
-    /* Offset stored by the segment (real offset from base incremented by 1) */
-    size_t segment_offset = aligned_shadow[0];
-    /* Base address */
-    uintptr_t base_addr = addr - block_offset - segment_offset + 1;
-    /* Pointer to the meta-segment */
-    uintptr_t *meta_segment =
-      (uintptr_t*)HEAP_SHADOW(base_addr - HEAP_SEGMENT);
-    /* Size of the block stored by meta-segment */
-    size_t length = meta_segment[1];
-    /* Offset of a given address within its block */
-    size_t offset = segment_offset - 1 + block_offset;
-    return offset + size <= length;
+  if (shadow[0]) {
+    uintptr_t *base_shadow =
+      (uintptr_t*)HEAP_SHADOW(base_ptr - base_ptr%HEAP_SEGMENT);
+    uintptr_t *first_segment = (uintptr_t*)HEAP_SHADOW(shadow[0]);
+    /* shadow[0] - base address of the tracked block
+     * fist_segment[1] - length (i.e., location in the first segment
+     *  after base address)
+     * offset is the difference between the address and base address (shadow[0])
+     * Then an address belongs to heap allocation if
+     *  offset + size <= length */
+    return base_shadow[0] == shadow[0] &&
+      (addr - shadow[0]) + size <= first_segment[1];
   }
   return 0;
 }
@@ -978,102 +1030,80 @@ static int heap_allocated(uintptr_t addr, size_t size) {
  * As some of the other functions, \b \\freeable can be expressed using
  * ::IS_ON_HEAP, ::heap_allocated and ::base_addr. Here direct
  * implementation is preferred for performance reasons. */
-static int freeable(void *ptr) {
+static int freeable(void *ptr) { /* + */
   uintptr_t addr = (uintptr_t)ptr;
+  /* Address is not on the program's heap, so cannot be freed */
   if (!IS_ON_HEAP(addr))
     return 0;
-  /* Offset within the segment */
-  size_t block_offset = addr%HEAP_SEGMENT;
-  /* Address of the shadow segment the address belongs to */
-  uintptr_t *aligned_shadow = (uintptr_t*)HEAP_SHADOW(addr - block_offset);
-  /* Non-zero if the segment belongs to heap allocation */
-  if (aligned_shadow[0])
-    return addr == addr - block_offset - aligned_shadow[0] + 1;
-  return 0;
-}
-
-/*! \brief Implementation of the \b \\initialized predicate for heap-allocated
- * memory. NB: If `addr` does not belong to a valid heap region this function
- * returns 0. */
-static int heap_initialized(uintptr_t addr, long len) {
-  /* Unallocated heap address */
-  if (!heap_allocated(addr, len))
-    return 0;
-
-  /* Do validate a block in debug mode otherwise */
-  DVALIDATE_HEAP_ACCESS(addr, len);
-  int result = 1;
 
-  /* Offset within the segment. Also the number of bits
-   * that needs to be skipped when evaluating init */
-  int skipbits = addr%HEAP_SEGMENT;
-
-  /* Base address of a shadow segment ptr belongs to */
-  uintptr_t shadow_init = (uintptr_t)(HEAP_SHADOW(addr) + PTR_SZ - skipbits);
-
-  int rem = HEAP_SEGMENT - skipbits;
-  /* The number of bits that need to be checked in the `first' segment */
-  int setbits = (len >= rem) ? rem : len;
-
-  len -= setbits;
-
-  /* Bit-mask for setting values. Tested bits are set to ones, the rest
-   * are zeroes. */
-  uint64_t mask = (ONE >> (ULONG_BITS - setbits)) << skipbits;
-
-  uint64_t *init = (uint64_t*)shadow_init;
-  result = result && ((mask & *init) == mask);
-  shadow_init += HEAP_SEGMENT;
-
-  while (len > 0) {
-    /* Recompute the number of bits to be set */
-    setbits = (len > HEAP_SEGMENT) ? HEAP_SEGMENT : len;
-    /* Reset the mask */
-    mask = ONE >> (ULONG_BITS - setbits);
-    /* Current position of shadow initialization */
-    init = (uint64_t*)shadow_init;
-
-    result = result && ((mask & *init) == mask);
-    len -= setbits;
-    shadow_init += HEAP_SEGMENT;
+  /* Address of the shadow segment the address belongs to */
+  uintptr_t *shadow = (uintptr_t*)ALIGNED_HEAP_SHADOW(addr);
+  /* Non-zero if the segment belongs to heap allocation with *shadow
+   * capturing the base address of the tracked block */
+  if (*shadow) {
+    /* Block is freeable if `addr` is the base address of its block  */
+    return (uintptr_t)*shadow == addr;
   }
-  return result;
+  return 0;
 }
 
 /*! \brief Querying information about a specific heap memory address.
  * This function is similar to ::static_info except it returns data
- * associated with heap-allocated memory.
+ * associated with dynamically allocated memory.
  * See in-line documentation for ::static_info for further details. */
 static uintptr_t heap_info(uintptr_t addr, char type) {
+  /* Ensure that `addr` is an allocated location on a program's heap */
   DVALIDATE_HEAP_ACCESS(addr, 1);
-  /* Offset within the segment */
-  size_t block_offset = addr%HEAP_SEGMENT;
-  /* Address of the shadow segment the address belongs to */
-  uintptr_t *aligned_shadow =
-    (uintptr_t*)HEAP_SHADOW(addr - block_offset);
-  /* Offset stored by the segment (real offset from base incremented by 1) */
-  size_t segment_offset = aligned_shadow[0];
-  /* Base address */
-  uintptr_t base_addr = addr - block_offset - segment_offset + 1;
+  /* Base address of the shadow segment the address belongs to.
+   * First `sizeof(uintptr_t)` bytes of each segment store application-level
+   * base address of the tracked block */
+  uintptr_t *aligned_shadow = (uintptr_t*)ALIGNED_HEAP_SHADOW(addr);
 
   switch(type) {
     case 'B': /* Base address */
-      return base_addr;
+      return *aligned_shadow;
     case 'L': { /* Block length */
-      /* Pointer to meta-segment */
-      uintptr_t *meta_segment =
-        (uintptr_t*)HEAP_SHADOW(base_addr - HEAP_SEGMENT);
-      /* Size of the block stored by meta-segment */
-      return meta_segment[1];
+      /* Pointer to the first-segment in the shadow block */
+      uintptr_t *base_segment = (uintptr_t*)HEAP_SHADOW(*aligned_shadow);
+      /* Length of the stored block is captured in `sizeof(uintptr_t)` bytes
+       * past `sizeof(uintptr_t)` tracking the base address */
+      return base_segment[1];
     }
     case 'O':
-      /* Offset of a given address within its block */
-      return segment_offset - 1 + block_offset;
+      /* Offset of a given address within its block. This is the difference
+       * between the input address and the base address of the block. */
+      return addr - *aligned_shadow;
     default:
       DASSERT(0 && "Unknown heap query type");
   }
   return 0;
 }
+
+/*! \brief Implementation of the \b \\initialized predicate for heap-allocated
+ * memory. NB: If `addr` does not belong to an allocated heap block this
+ * function returns 0. */
+static int heap_initialized(uintptr_t addr, long len) {
+  /* Base address of a shadow segment addr belongs to */
+  unsigned char *shadow = (unsigned char*)(HEAP_INIT_SHADOW(addr));
+
+  /* See comments in the `initialize_heap_region` function for more details */
+  unsigned skip = (addr - HEAP_START)%8;
+  unsigned set;
+  if (skip) {
+    set = 8 - skip;
+    set = (len > set) ? set : len;
+    len -= set;
+    unsigned char mask = 0;
+    setbits64_skip(set,mask,skip);
+
+    if (*shadow != mask)
+      return 0;
+  }
+  if (len > 0)
+    return checkbits(len,shadow);
+  return 1;
+}
+
 /* }}} */
 
 /* Heap initialization {{{ */
@@ -1085,38 +1115,47 @@ static void initialize_heap_region(uintptr_t addr, long len) {
     "starting at %a with block length %lu at base address %a\n",
     len, addr, block_length(addr), base_addr(addr));
 
-  /* Offset within the segment. Also the number of bits
-   * that needs to be skipped when evaluating init */
-  int skipbits = (addr)%HEAP_SEGMENT;
-
-  /* Base address of a shadow segment addr belongs to */
-  uintptr_t shadow_init = (uintptr_t)(HEAP_SHADOW(addr) + PTR_SZ - skipbits);
-
-  int rem = HEAP_SEGMENT - skipbits;
-  /* The number of bits that need to be checked in the `first' segment */
-  int setbits = (len >= rem) ? rem : len;
-
-  len -= setbits;
-
-  /* Bit-mask for setting values. Bits that are tested are set to ones, the
-   * rest are zeroes */
-  uint64_t mask = (ONE >> (ULONG_BITS - setbits)) << skipbits;
-
-  *(uint64_t*)shadow_init = *(uint64_t*)shadow_init | mask;
-  shadow_init += HEAP_SEGMENT;
+  /* Address within init shadow tracking initialization  */
+  unsigned char *shadow = (unsigned char*)(HEAP_INIT_SHADOW(addr));
+
+  /* First check whether the address in the init shadow is divisible by 8
+   * (i.e., located on a byte boundary) */
+  /* Leading bits in `*shadow` byte which do not need to be set
+   * (i.e., skipped) */
+  short skip = (addr - HEAP_START)%8;
+  if (skip) {
+    /* The remaining bits in the shadow byte */
+    short set = 8 - skip;
+    /* The length of initialized region can be short (shorter then the
+     * above remainder). Adjust the number of bits to set accordingly. */
+    set = (len > set) ? set : len;
+    len -= set;
+    setbits64_skip(set, *shadow, skip);
+    /* Move to the next location if there are more bits to set */
+    shadow++;
+  }
 
-  while (len > 0) {
-    /* Recompute the number of bits to be set */
-    setbits = (len > HEAP_SEGMENT) ? HEAP_SEGMENT : len;
-    /* Reset the mask */
-    mask = ONE >> (ULONG_BITS - setbits);
-    *(uint64_t*)shadow_init = *(uint64_t*)shadow_init | mask;
-    len -= setbits;
-    shadow_init += HEAP_SEGMENT;
+  if (len > 0) {
+    /* Set the remaining bits. Note `shadow` is now aligned at a byte
+     * boundary, thus one can set `len` bits starting with address given by
+     * `shadow` */
+    setbits(len, shadow);
   }
 }
 /* }}} */
 
+/* Any allocation {{{ */
+/*! \brief Amalgamation of ::heap_allocated and ::static_allocated */
+static int allocated(uintptr_t addr, long size, uintptr_t base) {
+  TRY_SEGMENT_WEAK(addr,
+    return heap_allocated(addr, size, base),
+    return static_allocated(addr, size, base));
+  if (!IS_ON_VALID(addr))
+    return 0;
+  return 0;
+}
+/* }}} */
+
 /* Any initialization {{{ */
 /*! \brief Initialize a chunk of memory given by its start address (`addr`)
  * and byte length (`n`). */
@@ -1173,20 +1212,39 @@ static void print_static_shadows(uintptr_t addr, size_t size) {
 }
 
 /*! \brief Print human-readable representation of a heap shadow region for a
- * memory block of length `size` starting at address `addr`.  */
-static void print_heap_shadows(uintptr_t addr, size_t size) {
-  unsigned char *shadowed = (unsigned char*)HEAP_SHADOW(addr);
-  uintptr_t *shadow_meta = (uintptr_t*)(shadowed - HEAP_SEGMENT);
-
-  size_t block_segments = (ALIGNED_SIZE(size))/HEAP_SEGMENT;
-  DLOG("Meta: %3lu", shadow_meta[1]);
+ * memory block of length `size` starting at address `addr`. This function
+ * assumes that `addr` is the base address of the memory block. */
+static void print_heap_shadows(uintptr_t addr) {
+  unsigned char *block_shadow = (unsigned char*)HEAP_SHADOW(addr);
+  unsigned char *init_shadow =  (unsigned char*)HEAP_INIT_SHADOW(addr);
+
+  size_t length = (size_t)((uintptr_t*)(block_shadow))[1];
+  size_t alloc_size = ALLOC_SIZE(length);
+  size_t segments = alloc_size/HEAP_SEGMENT;
+  uintptr_t *segment = (uintptr_t*)(block_shadow);
+
+  DLOG(" | === Block Shadow ======================================\n");
+  DLOG(" | Access addr:    %a\n",  addr);
+  DLOG(" | Block Shadow:   %a\n",	 block_shadow);
+  DLOG(" | Init	 Shadow:   %a\n",	 init_shadow);
+  DLOG(" | Segments:       %lu\n", segments);
+  DLOG(" | Actual size:    %lu bytes\n", alloc_size);
+  DLOG(" | Tracked Length: %lu bytes\n", length);
+
+  if (zeroed_out(block_shadow, alloc_size))
+    DLOG(" | << Nullified >>  \n");
 
   size_t i;
-  for (i = 0; i < block_segments; i++) {
-    uintptr_t *block_segment = (uintptr_t*)(shadowed + i*HEAP_SEGMENT);
-    DLOG("%s | Block %2lu, Offset %3lu, Init: %"
-      TOSTRING(HEAP_SEGMENT) "b\t\t || %a \n", i ? "         "  : "", i,
-      block_segment[0], block_segment[1],  block_segment);
+  for (i = 0; i < segments; i++) {
+    segment = (uintptr_t*)(block_shadow + i*HEAP_SEGMENT);
+    DLOG(" |   Segment: %lu, Base: %a \n", i, *segment);
+  }
+
+  DLOG(" | Initialization: \n |   ");
+  for (i = 0; i < alloc_size/8; i++) {
+    if (i > 0 && (i*8)%HEAP_SEGMENT == 0)
+      DLOG("\n |   ");
+    DLOG("%8b ", init_shadow[i], init_shadow[i]);
   }
   DLOG("\n");
 }
@@ -1195,22 +1253,16 @@ static void print_shadows(uintptr_t addr, size_t size) {
   if (IS_ON_STATIC(addr))
     print_static_shadows(addr, size);
   else if (IS_ON_HEAP(addr))
-    print_heap_shadows(addr, size);
+    print_heap_shadows(addr);
 }
 
 static void print_memory_segment(struct memory_segment *seg, const char *name) {
   DLOG(" --- %s ------------------------------------------\n", name);
-  DLOG("%s Shadow Size:               %16lu MB\n", name, MB_SZ(seg->shadow_size));
-  DLOG("%s Start:                     %19lu\n", name, seg->start);
-  DLOG("%s End:                       %19lu\n", name, seg->end);
-  DLOG("%s Primary Shadow Offset:     %19lu\n", name, seg->prim_offset);
-  DLOG("%s Primary Shadow Start:      %19lu\n", name, seg->prim_start);
-  DLOG("%s Primary Shadow End:        %19lu\n", name, seg->prim_end);
-  if (seg->sec_start) {
-    DLOG("%s Secondary Shadow Offset:   %19lu\n", name, seg->sec_offset);
-    DLOG("%s Secondary Shadow Start:    %19lu\n", name, seg->sec_start);
-    DLOG("%s Secondary Shadow End:      %19lu\n", name, seg->sec_end);
-  }
+  DLOG("Segment:   %lu MB [%a, %a]\n", MB_SZ(seg->size), seg->start, seg->end);
+  DLOG("Primary:   %lu MB [%a, %a] {Offset: %lu}\n",
+    MB_SZ(seg->prim_size), seg->prim_start, seg->prim_end, seg->prim_offset);
+  DLOG("Secondary: %lu MB [%a, %a] {Offset: %lu}\n",
+    MB_SZ(seg->sec_size), seg->sec_start, seg->sec_end, seg->sec_offset);
 }
 
 static void print_memory_layout() {
diff --git a/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_shadow_layout.h b/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_shadow_layout.h
index afe67693198baa0603f74fffa61d121d46732c46..2a2ff24bf9acab6fe668f65924e779677f5ba0c5 100644
--- a/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_shadow_layout.h
+++ b/src/plugins/e-acsl/share/e-acsl/segment_model/e_acsl_shadow_layout.h
@@ -68,7 +68,7 @@ char *strerror(int errnum);
 
 /** Hardcoded sizes of tracked program segments {{{ */
 /*! \brief Size of a program's heap */
-#define PGM_HEAP_SIZE (256 * MB)
+#define PGM_HEAP_SIZE (512 * MB)
 
 /*! \brief Size of a program's Thread-local storage (TLS) */
 #define PGM_TLS_SIZE (16 * MB)
@@ -136,8 +136,8 @@ static uintptr_t get_stack_start(int *argc_ref,  char *** argv_ref) {
     env++;
   uintptr_t addr = (uintptr_t)*env + strlen(*env);
 
-  /* When returning the end stack addess we need to make sure that
-   * ::ULONG_BITS past that address are actually writable. This is
+  /* When returning the end stack address we need to make sure that
+   * ::ULONG_BITS past that address are actually writeable. This is
    * to be able to set initialization and read-only bits ::ULONG_BITS
    * at a time. If not respected, this may cause a segfault in
    * ::argv_alloca. */
@@ -157,7 +157,7 @@ static void increase_stack_limit(const size_t size) {
       rl.rlim_cur = stacksz;
       result = setrlimit(RLIMIT_STACK, &rl);
       if (result != 0) {
-        vabort("setrlimit returned result = %d\n", result);
+        vabort("setrlimit: %s \n", strerror(errno));
       }
     }
   }
@@ -175,6 +175,13 @@ static uintptr_t get_heap_start() {
 static size_t get_heap_size() {
   return PGM_HEAP_SIZE;
 }
+
+/*! \brief Return the size of a secondary shadow region tracking
+ * initialization (i.e., init shadow). */
+static size_t get_heap_init_size() {
+  return get_heap_size()/8;
+}
+
 /** }}} */
 
 /** Program global information {{{ */
@@ -195,11 +202,12 @@ static size_t get_global_size() {
  * pointer to its base address. Since this function is used to set-up shadowing
  * the program is aborted if `mmap` fails to allocate a new memory block. */
 static void *do_mmap(size_t size) {
-  DLOG("<<< Request to allocate %lu bytes with mmap >>>\n", size);
   void *res = mmap(0, size, PROT_READ|PROT_WRITE,
     MAP_ANONYMOUS|MAP_PRIVATE, -1, (size_t)0);
-  if (res == MAP_FAILED)
+  if (res == MAP_FAILED) {
+    DLOG("<<< Request to allocate %lu MB with mmap failed >>>\n", MB_SZ(size));
     vabort("mmap error: %s\n", strerror(errno));
+  }
   /* Make sure that mmap returned a fully nullified mapping */
   DVASSERT(zeroed_out(res, size),
     "Memory mapping of size %lu at address %a not fully nullified", size, res);
@@ -264,17 +272,20 @@ NOTE: With mmap allocations heap does not necessarily grows from program break
  * shadow spaces. */
 struct memory_segment {
   const char *name;
-  uintptr_t start; //!< Least address in application segment
-  uintptr_t end; //!< Greatest address in application segment
-
-  size_t shadow_size; //!< Byte-size of shadow area
-
-  uintptr_t prim_start; //!< Least address in primary shadow
-  uintptr_t prim_end; //!< Greatest address in primary shadow
+  uintptr_t start; //!< Least address in the application segment
+  uintptr_t end; //!< Greatest address in the application segment
+  uintptr_t size; //!< Size of the tracked segment in application memory
+  /* Primary shadow space */
+  size_t    prim_size; //!< Byte-size of the primary shadow
+  size_t    prim_ratio; //! Ratio of shadow to application memory
+  uintptr_t prim_start; //!< Least address in the primary shadow
+  uintptr_t prim_end; //!< Greatest address in the primary shadow
   uintptr_t prim_offset; //!< Primary shadow offset
-
-  uintptr_t sec_start; //!< Least address secondary shadow
-  uintptr_t sec_end; //!< Greatest address secondary shadow
+  /* Secondary shadow space */
+  size_t    sec_size; //!< Byte-size of shadow area
+  size_t    sec_ratio; //! Ratio of shadow to application memory
+  uintptr_t sec_start; //!< Least address in the secondary shadow
+  uintptr_t sec_end; //!< Greatest address in the secondary shadow
   uintptr_t sec_offset; //!< Secondary shadow offset
 
   int initialized; //! Notion on whether the layout is initialized
@@ -291,24 +302,39 @@ struct memory_layout {
   int initialized;
 };
 
-/*! \brief Set a given memory segment and its shadow spaces. */
+/*! \brief Set a given memory segment and its shadow spaces.
+ *
+ * \param start - least address in an application's segment
+ * \param size - byte size of a tracked application's segment
+ * \param prim_ratio - compression ratio of the primary shadow segment
+ * \param sec_ratio - compression ratio of the secondary shadow segment
+ * \param name - segment name
+*/
 static void set_shadow_segment(struct memory_segment *seg, uintptr_t start,
-    size_t size, int secondary, const char *name) {
-  DLOG("<<< Initialize %s segment of %lu MB >>>\n", name, size/MB);
-  seg -> name = name;
-  seg->start = start;
-  seg->end = seg->start + size - 1;
-  seg->shadow_size = size;
+    size_t size, size_t prim_ratio, size_t sec_ratio, const char *name) {
 
-  void *prim_shadow = do_mmap(seg->shadow_size);
-  seg->prim_start = (uintptr_t)prim_shadow;
-  seg->prim_end = seg->prim_start + seg->shadow_size - 1;
-  seg->prim_offset = shadow_offset(prim_shadow, start);
+  seg->name = name;
+  seg->start = start;
+  seg->size = size;
+  seg->end = seg->start + seg->size - 1;
+
+  if (prim_ratio) {
+    seg->prim_ratio = prim_ratio;
+    seg->prim_size = seg->size/seg->prim_ratio;
+    void *prim_shadow = do_mmap(seg->prim_size);
+    seg->prim_start = (uintptr_t)prim_shadow;
+    seg->prim_end = seg->prim_start + seg->prim_size - 1;
+    seg->prim_offset = shadow_offset(prim_shadow, start);
+  } else {
+    seg->prim_start = seg->prim_end = seg->prim_offset = 0;
+  }
 
-  if (secondary) {
-    void *sec_shadow = do_mmap(seg->shadow_size);
+  if (sec_ratio) {
+    seg->sec_ratio = sec_ratio;
+    seg->sec_size = seg->size/seg->sec_ratio;
+    void *sec_shadow = do_mmap(seg->sec_size);
     seg->sec_start = (uintptr_t)sec_shadow;
-    seg->sec_end = seg->sec_start + seg->shadow_size - 1;
+    seg->sec_end = seg->sec_start + seg->sec_size - 1;
     seg->sec_offset = shadow_offset(sec_shadow, seg->start);
   } else {
     seg->sec_start = seg->sec_end = seg->sec_offset = 0;
@@ -319,32 +345,34 @@ static void set_shadow_segment(struct memory_segment *seg, uintptr_t start,
  * allocate shadow memory spaces and compute offsets. This function populates
  * global struct ::mem_layout holding that information with data. */
 static void init_memory_layout(int *argc_ref, char ***argv_ref) {
+  /* Use DEBUG_PRINT_LAYOUT to output the details (if they are needed) */
   set_shadow_segment(&mem_layout.heap,
-    get_heap_start(), get_heap_size(), 0, "heap");
+    get_heap_start(), get_heap_size(), 1, 8, "heap");
   set_shadow_segment(&mem_layout.stack,
-    get_stack_start(argc_ref, argv_ref), get_stack_size(), 1, "stack");
+    get_stack_start(argc_ref, argv_ref), get_stack_size(), 1, 1, "stack");
   set_shadow_segment(&mem_layout.global,
-    get_global_start(), get_global_size(), 1, "global");
+    get_global_start(), get_global_size(), 1, 1, "global");
   set_shadow_segment(&mem_layout.tls,
-    get_tls_start(), get_tls_size(), 1, "tls");
+    get_tls_start(), get_tls_size(), 1, 1, "tls");
   mem_layout.initialized = 1;
 }
 
 /*! \brief Deallocate a shadow segment */
-void clean_memory_segment(struct memory_segment *seg, int secondary) {
-  munmap((void*)seg->prim_start, seg->shadow_size);
-  if (secondary)
-    munmap((void*)seg->sec_start, seg->shadow_size);
+void clean_memory_segment(struct memory_segment *seg) {
+  if (seg->prim_start)
+    munmap((void*)seg->prim_start, seg->prim_size);
+  if (seg->sec_start)
+    munmap((void*)seg->sec_start, seg->prim_size);
 }
 
 /*! \brief Deallocate shadow regions used by runtime analysis */
 static void clean_memory_layout() {
   DLOG("<<< Clean shadow layout >>>\n");
   if (mem_layout.initialized) {
-    clean_memory_segment(&mem_layout.heap, 0);
-    clean_memory_segment(&mem_layout.stack, 1);
-    clean_memory_segment(&mem_layout.global, 1);
-    clean_memory_segment(&mem_layout.tls, 1);
+    clean_memory_segment(&mem_layout.heap);
+    clean_memory_segment(&mem_layout.stack);
+    clean_memory_segment(&mem_layout.global);
+    clean_memory_segment(&mem_layout.tls);
   }
 }
 /* }}} */
@@ -381,6 +409,24 @@ static void clean_memory_layout() {
 #define HIGHER_SHADOW_ACCESS(_addr,_offset) \
   SHADOW_ACCESS(_addr,_offset,+)
 
+/*! \brief Same as SHADOW_ACCESS but with an additional scale factor given via
+ * _scale argument. Scale factor describes ratio of application to shadow bytes,
+ * for instance if one bit shadow memory is used to track one byte of
+ * application memory then the scale factor is 8. */
+#define SCALED_SHADOW_ACCESS(_addr,_start,_offset,_scale,_direction)  \
+  (_addr _direction \
+    (_offset - \
+      ((uintptr_t)_addr - _start) + \
+      ((uintptr_t)_addr - _start)/_scale))
+
+/*! \brief Same as `LOWER_SHADOW_ACCESS` but with an additional scale factor */
+#define LOWER_SCALED_SHADOW_ACCESS(_addr,_start,_offset,_scale)  \
+  SCALED_SHADOW_ACCESS(_addr,_start,_offset,_scale, -)
+
+/*! \brief Same as `HIGHER_SHADOW_ACCESS` but with an additional scale factor */
+#define HIGHER_SCALED_SHADOW_ACCESS(_addr,_start,_offset,_scale)  \
+  SCALED_SHADOW_ACCESS(_addr,_start,_offset,_scale, +)
+
 /*! \brief Convert a stack address into its primary shadow counterpart */
 #define PRIMARY_STACK_SHADOW(_addr) \
   LOWER_SHADOW_ACCESS(_addr, mem_layout.stack.prim_offset)
@@ -421,6 +467,16 @@ static void clean_memory_layout() {
 /*! \brief Convert a heap address into its shadow counterpart */
 #define HEAP_SHADOW(_addr) \
   HIGHER_SHADOW_ACCESS(_addr, mem_layout.heap.prim_offset)
+
+#define HEAP_START mem_layout.heap.start
+
+/*! \brief Convert a heap address into its init shadow counterpart */
+#define HEAP_INIT_SHADOW(_addr) \
+  HIGHER_SCALED_SHADOW_ACCESS(_addr, \
+      mem_layout.heap.start, \
+      mem_layout.heap.sec_offset, \
+      mem_layout.heap.sec_ratio)
+
 /* }}} */
 
 /** Memory segment ranges {{{ */
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c
index 7cc4edfe216c6307c95229f8b11bb0ba03b30c96..5717cea664861ca0917acd17d42a8851651ba87e 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1307.c
@@ -121,13 +121,18 @@ void __gen_e_acsl_bar(float *Mtmin_in, float *Mwmin, float *Mtmin_out)
     __e_acsl_store_block((void *)(& Mtmin_out),(size_t)8);
     __e_acsl_store_block((void *)(& Mwmin),(size_t)8);
     __e_acsl_store_block((void *)(& Mtmin_in),(size_t)8);
-    __gen_e_acsl_valid = __e_acsl_valid((void *)Mtmin_in,sizeof(float));
+    __gen_e_acsl_valid = __e_acsl_valid((void *)Mtmin_in,sizeof(float),
+                                        (void *)Mtmin_in,
+                                        (void *)(& Mtmin_in));
     __e_acsl_assert(__gen_e_acsl_valid,(char *)"Precondition",(char *)"bar",
                     (char *)"\\valid(Mtmin_in)",17);
-    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)Mwmin,sizeof(float));
+    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)Mwmin,sizeof(float),
+                                          (void *)Mwmin,(void *)(& Mwmin));
     __e_acsl_assert(__gen_e_acsl_valid_2,(char *)"Precondition",
                     (char *)"bar",(char *)"\\valid(Mwmin)",18);
-    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)Mtmin_out,sizeof(float));
+    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)Mtmin_out,sizeof(float),
+                                          (void *)Mtmin_out,
+                                          (void *)(& Mtmin_out));
     __e_acsl_assert(__gen_e_acsl_valid_3,(char *)"Precondition",
                     (char *)"bar",(char *)"\\valid(Mtmin_out)",19);
     __gen_e_acsl_at_6 = Mwmin;
@@ -144,23 +149,31 @@ void __gen_e_acsl_bar(float *Mtmin_in, float *Mwmin, float *Mtmin_out)
     int __gen_e_acsl_and;
     int __gen_e_acsl_if;
     __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)__gen_e_acsl_at_2,
-                                                  sizeof(float));
+                                                  sizeof(float),
+                                                  (void *)__gen_e_acsl_at_2,
+                                                  (void *)(& __gen_e_acsl_at_2));
     __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"bar",
                     (char *)"mem_access: \\valid_read(__gen_e_acsl_at_2)",23);
     __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)__gen_e_acsl_at,
-                                                    sizeof(float));
+                                                    sizeof(float),
+                                                    (void *)__gen_e_acsl_at,
+                                                    (void *)(& __gen_e_acsl_at));
     __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",(char *)"bar",
                     (char *)"mem_access: \\valid_read(__gen_e_acsl_at)",23);
     if (*__gen_e_acsl_at == *__gen_e_acsl_at_2) {
       int __gen_e_acsl_valid_read_3;
       int __gen_e_acsl_valid_read_4;
       __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)__gen_e_acsl_at_4,
-                                                      sizeof(float));
+                                                      sizeof(float),
+                                                      (void *)__gen_e_acsl_at_4,
+                                                      (void *)(& __gen_e_acsl_at_4));
       __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",(char *)"bar",
                       (char *)"mem_access: \\valid_read(__gen_e_acsl_at_4)",
                       23);
       __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)__gen_e_acsl_at_3,
-                                                      sizeof(float));
+                                                      sizeof(float),
+                                                      (void *)__gen_e_acsl_at_3,
+                                                      (void *)(& __gen_e_acsl_at_3));
       __e_acsl_assert(__gen_e_acsl_valid_read_4,(char *)"RTE",(char *)"bar",
                       (char *)"mem_access: \\valid_read(__gen_e_acsl_at_3)",
                       23);
@@ -170,7 +183,9 @@ void __gen_e_acsl_bar(float *Mtmin_in, float *Mwmin, float *Mtmin_out)
     if (__gen_e_acsl_and) {
       int __gen_e_acsl_valid_read_5;
       __gen_e_acsl_valid_read_5 = __e_acsl_valid_read((void *)__gen_e_acsl_at_5,
-                                                      sizeof(float));
+                                                      sizeof(float),
+                                                      (void *)__gen_e_acsl_at_5,
+                                                      (void *)(& __gen_e_acsl_at_5));
       __e_acsl_assert(__gen_e_acsl_valid_read_5,(char *)"RTE",(char *)"bar",
                       (char *)"mem_access: \\valid_read(__gen_e_acsl_at_5)",
                       23);
@@ -179,7 +194,9 @@ void __gen_e_acsl_bar(float *Mtmin_in, float *Mwmin, float *Mtmin_out)
     else {
       int __gen_e_acsl_valid_read_6;
       __gen_e_acsl_valid_read_6 = __e_acsl_valid_read((void *)__gen_e_acsl_at_6,
-                                                      sizeof(float));
+                                                      sizeof(float),
+                                                      (void *)__gen_e_acsl_at_6,
+                                                      (void *)(& __gen_e_acsl_at_6));
       __e_acsl_assert(__gen_e_acsl_valid_read_6,(char *)"RTE",(char *)"bar",
                       (char *)"mem_access: \\valid_read(__gen_e_acsl_at_6)",
                       23);
@@ -217,13 +234,18 @@ void __gen_e_acsl_foo(float *Mtmax_in, float *Mwmax, float *Mtmax_out)
     __e_acsl_store_block((void *)(& Mtmax_out),(size_t)8);
     __e_acsl_store_block((void *)(& Mwmax),(size_t)8);
     __e_acsl_store_block((void *)(& Mtmax_in),(size_t)8);
-    __gen_e_acsl_valid = __e_acsl_valid((void *)Mtmax_in,sizeof(float));
+    __gen_e_acsl_valid = __e_acsl_valid((void *)Mtmax_in,sizeof(float),
+                                        (void *)Mtmax_in,
+                                        (void *)(& Mtmax_in));
     __e_acsl_assert(__gen_e_acsl_valid,(char *)"Precondition",(char *)"foo",
                     (char *)"\\valid(Mtmax_in)",5);
-    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)Mwmax,sizeof(float));
+    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)Mwmax,sizeof(float),
+                                          (void *)Mwmax,(void *)(& Mwmax));
     __e_acsl_assert(__gen_e_acsl_valid_2,(char *)"Precondition",
                     (char *)"foo",(char *)"\\valid(Mwmax)",6);
-    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)Mtmax_out,sizeof(float));
+    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)Mtmax_out,sizeof(float),
+                                          (void *)Mtmax_out,
+                                          (void *)(& Mtmax_out));
     __e_acsl_assert(__gen_e_acsl_valid_3,(char *)"Precondition",
                     (char *)"foo",(char *)"\\valid(Mtmax_out)",7);
     __gen_e_acsl_at_3 = Mwmax;
@@ -236,15 +258,21 @@ void __gen_e_acsl_foo(float *Mtmax_in, float *Mwmax, float *Mtmax_out)
     int __gen_e_acsl_valid_read_2;
     int __gen_e_acsl_valid_read_3;
     __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)__gen_e_acsl_at_3,
-                                                  sizeof(float));
+                                                  sizeof(float),
+                                                  (void *)__gen_e_acsl_at_3,
+                                                  (void *)(& __gen_e_acsl_at_3));
     __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"foo",
                     (char *)"mem_access: \\valid_read(__gen_e_acsl_at_3)",11);
     __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)__gen_e_acsl_at_2,
-                                                    sizeof(float));
+                                                    sizeof(float),
+                                                    (void *)__gen_e_acsl_at_2,
+                                                    (void *)(& __gen_e_acsl_at_2));
     __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",(char *)"foo",
                     (char *)"mem_access: \\valid_read(__gen_e_acsl_at_2)",11);
     __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)__gen_e_acsl_at,
-                                                    sizeof(float));
+                                                    sizeof(float),
+                                                    (void *)__gen_e_acsl_at,
+                                                    (void *)(& __gen_e_acsl_at));
     __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",(char *)"foo",
                     (char *)"mem_access: \\valid_read(__gen_e_acsl_at)",11);
     __e_acsl_assert(*__gen_e_acsl_at == *__gen_e_acsl_at_2 + ((long double)5 - 
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1324.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1324.c
index 22ff3c673342aadefb8e35967fd01932dd0f3d38..04cb8cbdf7534223386e6d7ad5e7ab96680c50fc 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1324.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1324.c
@@ -67,14 +67,17 @@ int __gen_e_acsl_sorted(int *t, int n)
         int __gen_e_acsl_valid_read;
         int __gen_e_acsl_valid_read_2;
         __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(t + __gen_e_acsl_i),
-                                                      sizeof(int));
+                                                      sizeof(int),(void *)t,
+                                                      (void *)(& t));
         __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",
                         (char *)"sorted",
                         (char *)"mem_access: \\valid_read(t + __gen_e_acsl_i)",
                         6);
         __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(t + (
                                                                  __gen_e_acsl_i - 1L)),
-                                                        sizeof(int));
+                                                        sizeof(int),
+                                                        (void *)t,
+                                                        (void *)(& t));
         __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",
                         (char *)"sorted",
                         (char *)"mem_access: \\valid_read(t + (long)(__gen_e_acsl_i - 1))",
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1326.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1326.c
index ab9d25dbf699d44b02f3ef9c205537dfdb309abb..847be00d2729b5edcb71933b1e8656473daeabcf 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1326.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1326.c
@@ -79,37 +79,49 @@ void __gen_e_acsl_atp_NORMAL_computeAverageAccel(ArrayInt *Accel,
     int __gen_e_acsl_valid_read_5;
     int __gen_e_acsl_valid_read_6;
     __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(*__gen_e_acsl_at_6),
-                                                  sizeof(int));
+                                                  sizeof(int),
+                                                  (void *)(*__gen_e_acsl_at_6),
+                                                  (void *)(*__gen_e_acsl_at_6));
     __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",
                     (char *)"atp_NORMAL_computeAverageAccel",
                     (char *)"mem_access: \\valid_read((int *)*__gen_e_acsl_at_6)",
                     8);
     __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(& (*__gen_e_acsl_at_5)[1]),
-                                                    sizeof(int));
+                                                    sizeof(int),
+                                                    (void *)(& (*__gen_e_acsl_at_5)[1]),
+                                                    (void *)(& (*__gen_e_acsl_at_5)[1]));
     __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",
                     (char *)"atp_NORMAL_computeAverageAccel",
                     (char *)"mem_access: \\valid_read(&(*__gen_e_acsl_at_5)[1])",
                     8);
     __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)(& (*__gen_e_acsl_at_4)[2]),
-                                                    sizeof(int));
+                                                    sizeof(int),
+                                                    (void *)(& (*__gen_e_acsl_at_4)[2]),
+                                                    (void *)(& (*__gen_e_acsl_at_4)[2]));
     __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",
                     (char *)"atp_NORMAL_computeAverageAccel",
                     (char *)"mem_access: \\valid_read(&(*__gen_e_acsl_at_4)[2])",
                     8);
     __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)(& (*__gen_e_acsl_at_3)[3]),
-                                                    sizeof(int));
+                                                    sizeof(int),
+                                                    (void *)(& (*__gen_e_acsl_at_3)[3]),
+                                                    (void *)(& (*__gen_e_acsl_at_3)[3]));
     __e_acsl_assert(__gen_e_acsl_valid_read_4,(char *)"RTE",
                     (char *)"atp_NORMAL_computeAverageAccel",
                     (char *)"mem_access: \\valid_read(&(*__gen_e_acsl_at_3)[3])",
                     8);
     __gen_e_acsl_valid_read_5 = __e_acsl_valid_read((void *)(& (*__gen_e_acsl_at_2)[4]),
-                                                    sizeof(int));
+                                                    sizeof(int),
+                                                    (void *)(& (*__gen_e_acsl_at_2)[4]),
+                                                    (void *)(& (*__gen_e_acsl_at_2)[4]));
     __e_acsl_assert(__gen_e_acsl_valid_read_5,(char *)"RTE",
                     (char *)"atp_NORMAL_computeAverageAccel",
                     (char *)"mem_access: \\valid_read(&(*__gen_e_acsl_at_2)[4])",
                     8);
     __gen_e_acsl_valid_read_6 = __e_acsl_valid_read((void *)__gen_e_acsl_at,
-                                                    sizeof(int));
+                                                    sizeof(int),
+                                                    (void *)__gen_e_acsl_at,
+                                                    (void *)(& __gen_e_acsl_at));
     __e_acsl_assert(__gen_e_acsl_valid_read_6,(char *)"RTE",
                     (char *)"atp_NORMAL_computeAverageAccel",
                     (char *)"mem_access: \\valid_read(__gen_e_acsl_at)",8);
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1390.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1390.c
index b3b07a810c4810f60ea45889e8a3a4ba0875f260..d162a6aa8af1d3950d49a402bad992c1dd71b1b4 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1390.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1390.c
@@ -86,7 +86,9 @@ void *__gen_e_acsl_memchr(void const *buf, int c, size_t n)
       {
         int __gen_e_acsl_valid_read_3;
         __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)((char *)buf + __gen_e_acsl_k),
-                                                        sizeof(char));
+                                                        sizeof(char),
+                                                        (void *)buf,
+                                                        (void *)(& buf));
         __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",
                         (char *)"memchr",
                         (char *)"mem_access: \\valid_read((char *)buf + __gen_e_acsl_k)",
@@ -114,7 +116,9 @@ void *__gen_e_acsl_memchr(void const *buf, int c, size_t n)
       {
         int __gen_e_acsl_valid_read;
         __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)((char *)buf + __gen_e_acsl_i),
-                                                      sizeof(char));
+                                                      sizeof(char),
+                                                      (void *)buf,
+                                                      (void *)(& buf));
         __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",
                         (char *)"memchr",
                         (char *)"mem_access: \\valid_read((char *)buf + __gen_e_acsl_i)",
@@ -151,7 +155,9 @@ void *__gen_e_acsl_memchr(void const *buf, int c, size_t n)
         {
           int __gen_e_acsl_valid_read_2;
           __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)((char *)__gen_e_acsl_at_2 + __gen_e_acsl_j),
-                                                          sizeof(char));
+                                                          sizeof(char),
+                                                          (void *)__gen_e_acsl_at_2,
+                                                          (void *)(& __gen_e_acsl_at_2));
           __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",
                           (char *)"memchr",
                           (char *)"mem_access: \\valid_read((char *)__gen_e_acsl_at_2 + __gen_e_acsl_j)",
@@ -189,11 +195,11 @@ void __e_acsl_globals_init(void)
   __gen_e_acsl_literal_string = "toto";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,sizeof("toto"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   __gen_e_acsl_literal_string_2 = "tata";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_2,sizeof("tata"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_2);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_2);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_2);
   return;
 }
 
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1478.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1478.c
index 6b0fb4d512e7d921fd31fe45a5d6486a8ccce33e..6e3a6dfa88ee40d0fd1d3c907dee3889c686d5da 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1478.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1478.c
@@ -29,7 +29,9 @@ void __gen_e_acsl_loop(void)
     int __gen_e_acsl_valid;
     __e_acsl_assert(global_i == 0,(char *)"Precondition",(char *)"loop",
                     (char *)"global_i == 0",9);
-    __gen_e_acsl_valid = __e_acsl_valid((void *)global_i_ptr,sizeof(int));
+    __gen_e_acsl_valid = __e_acsl_valid((void *)global_i_ptr,sizeof(int),
+                                        (void *)global_i_ptr,
+                                        (void *)(& global_i_ptr));
     __e_acsl_assert(__gen_e_acsl_valid,(char *)"Precondition",(char *)"loop",
                     (char *)"\\valid(global_i_ptr)",10);
     __e_acsl_assert(global_i_ptr == & global_i,(char *)"Precondition",
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1700.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1700.c
index 0170ff8665ae278e2536dd65456af82665ca79d6..17c06da00028f0507772d51ccfa8a71c55f5cd43 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1700.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1700.c
@@ -14,7 +14,8 @@ int main(void)
   /*@ assert \valid(&s); */
   {
     int __gen_e_acsl_valid;
-    __gen_e_acsl_valid = __e_acsl_valid((void *)(& s),sizeof(struct toto));
+    __gen_e_acsl_valid = __e_acsl_valid((void *)(& s),sizeof(struct toto),
+                                        (void *)(& s),(void *)(& s));
     __e_acsl_assert(__gen_e_acsl_valid,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(&s)",9);
   }
@@ -28,7 +29,8 @@ int main(void)
                                                     sizeof(struct toto *));
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid_2;
-      __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(struct toto));
+      __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(struct toto),
+                                            (void *)p,(void *)(& p));
       __gen_e_acsl_and = __gen_e_acsl_valid_2;
     }
     else __gen_e_acsl_and = 0;
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1717.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1717.c
index cdf251232dd40241b8adc40535bdfaad166fd255..8849e28f584d838d51d8ca051fbd5b9802932821 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1717.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1717.c
@@ -19,7 +19,8 @@ int main(void)
                                                       sizeof(int *));
       if (__gen_e_acsl_initialized) {
         int __gen_e_acsl_valid;
-        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                            (void *)(& p));
         __gen_e_acsl_and = __gen_e_acsl_valid;
       }
       else __gen_e_acsl_and = 0;
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1718.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1718.c
index ac14adc8208dad17a2bb801052e7cdeab0bc7924..6a1f48467405e520ce022c13c0ce394a8edcf3f6 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1718.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1718.c
@@ -19,7 +19,8 @@ int main(void)
                                                       sizeof(int *));
       if (__gen_e_acsl_initialized) {
         int __gen_e_acsl_valid;
-        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                            (void *)(& p));
         __gen_e_acsl_and = __gen_e_acsl_valid;
       }
       else __gen_e_acsl_and = 0;
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1740.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1740.c
index 8a8c2d0efb0e6345b3ce1dc5c46df9c181b6efa7..1be5aa98ba9199f85d66a4d0da156a02c667e2b9 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1740.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1740.c
@@ -20,7 +20,8 @@ int main(void)
                                                       sizeof(int *));
       if (__gen_e_acsl_initialized) {
         int __gen_e_acsl_valid;
-        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                            (void *)(& p));
         __gen_e_acsl_and = __gen_e_acsl_valid;
       }
       else __gen_e_acsl_and = 0;
@@ -41,7 +42,8 @@ int main(void)
       if (__gen_e_acsl_initialized_2) {
         int __gen_e_acsl_valid_2;
         /*@ assert Value: dangling_pointer: ¬\dangling(&p); */
-        __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(int),
+                                              (void *)p,(void *)(& p));
         __gen_e_acsl_and_2 = __gen_e_acsl_valid_2;
       }
       else __gen_e_acsl_and_2 = 0;
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1837.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1837.c
index d84585a438def65bbddfabf6fd213f19a16ae358..26fe680be04f9f5a32ed9b49e43e941e3a6751a8 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts1837.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts1837.c
@@ -16,7 +16,8 @@ int f(void)
   /*@ assert \valid_read(S); */
   {
     int __gen_e_acsl_valid_read;
-    __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)S,sizeof(char));
+    __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)S,sizeof(char),
+                                                  (void *)S,(void *)(& S));
     __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"Assertion",(char *)"f",
                     (char *)"\\valid_read(S)",10);
   }
@@ -29,7 +30,9 @@ int f(void)
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid_read_2;
       __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)s1,
-                                                      sizeof(char));
+                                                      sizeof(char),
+                                                      (void *)s1,
+                                                      (void *)(& s1));
       __gen_e_acsl_and = __gen_e_acsl_valid_read_2;
     }
     else __gen_e_acsl_and = 0;
@@ -45,7 +48,9 @@ int f(void)
     if (__gen_e_acsl_initialized_2) {
       int __gen_e_acsl_valid_read_3;
       __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)s2,
-                                                      sizeof(char));
+                                                      sizeof(char),
+                                                      (void *)s2,
+                                                      (void *)(& s2));
       __gen_e_acsl_and_2 = __gen_e_acsl_valid_read_3;
     }
     else __gen_e_acsl_and_2 = 0;
@@ -63,15 +68,15 @@ void __e_acsl_globals_init(void)
   __gen_e_acsl_literal_string_3 = "toto";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_3,sizeof("toto"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_3);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_3);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_3);
   __gen_e_acsl_literal_string = "foo";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,sizeof("foo"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   __gen_e_acsl_literal_string_2 = "bar";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_2,sizeof("bar"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_2);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_2);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_2);
   __e_acsl_store_block((void *)(& S),(size_t)8);
   __e_acsl_full_init((void *)(& S));
   return;
@@ -105,7 +110,9 @@ int main(void)
         if (__gen_e_acsl_initialized) {
           int __gen_e_acsl_valid_read;
           __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)s,
-                                                        sizeof(char));
+                                                        sizeof(char),
+                                                        (void *)s,
+                                                        (void *)(& s));
           __gen_e_acsl_and = __gen_e_acsl_valid_read;
         }
         else __gen_e_acsl_and = 0;
@@ -120,7 +127,8 @@ int main(void)
                                                           sizeof(char *));
         if (__gen_e_acsl_initialized_2) {
           int __gen_e_acsl_valid;
-          __gen_e_acsl_valid = __e_acsl_valid((void *)s,sizeof(char));
+          __gen_e_acsl_valid = __e_acsl_valid((void *)s,sizeof(char),
+                                              (void *)s,(void *)(& s));
           __gen_e_acsl_and_2 = __gen_e_acsl_valid;
         }
         else __gen_e_acsl_and_2 = 0;
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts2191.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts2191.c
index 5e8086f82bea77b224d55d81d889ebe7697f0768..4ea2172ad1471759b70afc0abce442beb023b5e5 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts2191.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts2191.c
@@ -15,12 +15,12 @@ void __e_acsl_globals_init(void)
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,
                        sizeof("Struct_G[1]"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   __gen_e_acsl_literal_string_2 = "Struct_G[0]";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_2,
                        sizeof("Struct_G[0]"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_2);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_2);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_2);
   __e_acsl_store_block((void *)(_G),(size_t)32);
   __e_acsl_full_init((void *)(& _G));
   return;
@@ -40,7 +40,9 @@ int main(int argc, char **argv)
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid_read;
       __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)_G[0].str,
-                                                    sizeof(char));
+                                                    sizeof(char),
+                                                    (void *)_G[0].str,
+                                                    (void *)(& _G[0].str));
       __gen_e_acsl_and = __gen_e_acsl_valid_read;
     }
     else __gen_e_acsl_and = 0;
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts2192.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts2192.c
index f4dad2e66aaa4366edad123fbc03886896b6ccea..c56a8ba6a99fc28deda2c79dc3146c59fe5c74f0 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts2192.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts2192.c
@@ -8,7 +8,7 @@ void __e_acsl_globals_init(void)
   __gen_e_acsl_literal_string = "134";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,sizeof("134"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   __e_acsl_store_block((void *)(& n),(size_t)8);
   __e_acsl_full_init((void *)(& n));
   return;
diff --git a/src/plugins/e-acsl/tests/bts/oracle/gen_bts2252.c b/src/plugins/e-acsl/tests/bts/oracle/gen_bts2252.c
index 40e382aaa79ce831c673bd5e35afe8397bfd07f2..c4b1763467a908e2b079af0fe924a827e6cb6584 100644
--- a/src/plugins/e-acsl/tests/bts/oracle/gen_bts2252.c
+++ b/src/plugins/e-acsl/tests/bts/oracle/gen_bts2252.c
@@ -14,7 +14,7 @@ void __e_acsl_globals_init(void)
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,
                        sizeof("Test Code"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   return;
 }
 
@@ -37,7 +37,9 @@ int main(void)
       {
         int __gen_e_acsl_valid_read;
         __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(srcbuf + i),
-                                                      sizeof(char));
+                                                      sizeof(char),
+                                                      (void *)srcbuf,
+                                                      (void *)(& srcbuf));
         __e_acsl_assert(! __gen_e_acsl_valid_read,(char *)"Assertion",
                         (char *)"main",(char *)"!\\valid_read(srcbuf + i)",
                         16);
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_at.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_at.c
index 946f190171e905dfe251acbcae35c04d2d5dbf05..0be34f3867c94a594016eb9589084e0d1dd513c4 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_at.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_at.c
@@ -49,14 +49,17 @@ void g(int *p, int *q)
   L1:
     {
       int __gen_e_acsl_valid_read_3;
-      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)q,sizeof(int));
+      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)q,sizeof(int),
+                                                      (void *)q,
+                                                      (void *)(& q));
       __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",(char *)"g",
                       (char *)"mem_access: \\valid_read(q)",28);
       __gen_e_acsl_at_3 = *q;
     }
     {
       int __gen_e_acsl_valid_read;
-      __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)q,sizeof(int));
+      __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)q,sizeof(int),
+                                                    (void *)q,(void *)(& q));
       __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"g",
                       (char *)"mem_access: \\valid_read(q)",26);
       __gen_e_acsl_at = *q;
@@ -71,7 +74,8 @@ void g(int *p, int *q)
     {
       int __gen_e_acsl_valid_read_2;
       __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(p + __gen_e_acsl_at),
-                                                      sizeof(int));
+                                                      sizeof(int),(void *)p,
+                                                      (void *)(& p));
       __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",(char *)"g",
                       (char *)"mem_access: \\valid_read(p + __gen_e_acsl_at)",
                       26);
@@ -86,7 +90,8 @@ void g(int *p, int *q)
     {
       int __gen_e_acsl_valid_read_4;
       __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)(p + __gen_e_acsl_at_3),
-                                                      sizeof(int));
+                                                      sizeof(int),(void *)p,
+                                                      (void *)(& p));
       __e_acsl_assert(__gen_e_acsl_valid_read_4,(char *)"RTE",(char *)"g",
                       (char *)"mem_access: \\valid_read(p + __gen_e_acsl_at_3)",
                       28);
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_at2.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_at2.c
index 3a2801d937d13987851dbfb9077ff4049a036327..832354a78aa7c3b9a7165766abfc17b58e1206e8 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_at2.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_at2.c
@@ -106,14 +106,17 @@ void g(int *p, int *q)
   L1:
     {
       int __gen_e_acsl_valid_read_3;
-      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)q,sizeof(int));
+      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)q,sizeof(int),
+                                                      (void *)q,
+                                                      (void *)(& q));
       __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",(char *)"g",
                       (char *)"mem_access: \\valid_read(q)",28);
       __gen_e_acsl_at_3 = *q;
     }
     {
       int __gen_e_acsl_valid_read;
-      __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)q,sizeof(int));
+      __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)q,sizeof(int),
+                                                    (void *)q,(void *)(& q));
       __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"g",
                       (char *)"mem_access: \\valid_read(q)",26);
       __gen_e_acsl_at = *q;
@@ -129,7 +132,8 @@ void g(int *p, int *q)
       int __gen_e_acsl_valid_read_2;
       __e_acsl_mpz_t __gen_e_acsl_;
       __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(p + __gen_e_acsl_at),
-                                                      sizeof(int));
+                                                      sizeof(int),(void *)p,
+                                                      (void *)(& p));
       __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",(char *)"g",
                       (char *)"mem_access: \\valid_read(p + __gen_e_acsl_at)",
                       26);
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c
index 807d9d488710d3686b2777ee7ed5745a9a630b6b..87cf1db55b4d8b9c98996d38cfc0f866b8f09e42 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif.c
@@ -201,7 +201,9 @@ int main(void)
         {
           int __gen_e_acsl_valid;
           __gen_e_acsl_valid = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i]),
-                                              sizeof(int));
+                                              sizeof(int),
+                                              (void *)(& buf[__gen_e_acsl_i]),
+                                              (void *)(& buf[__gen_e_acsl_i]));
           if (__gen_e_acsl_valid) ;
           else {
             __gen_e_acsl_forall_7 = 0;
@@ -227,7 +229,9 @@ int main(void)
         {
           int __gen_e_acsl_valid_2;
           __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_2]),
-                                                sizeof(int));
+                                                sizeof(int),
+                                                (void *)(& buf[__gen_e_acsl_i_2]),
+                                                (void *)(& buf[__gen_e_acsl_i_2]));
           if (__gen_e_acsl_valid_2) ;
           else {
             __gen_e_acsl_forall_8 = 0;
@@ -253,7 +257,9 @@ int main(void)
         {
           int __gen_e_acsl_valid_3;
           __gen_e_acsl_valid_3 = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_3]),
-                                                sizeof(int));
+                                                sizeof(int),
+                                                (void *)(& buf[__gen_e_acsl_i_3]),
+                                                (void *)(& buf[__gen_e_acsl_i_3]));
           if (__gen_e_acsl_valid_3) ;
           else {
             __gen_e_acsl_forall_9 = 0;
@@ -296,7 +302,9 @@ int main(void)
           int __gen_e_acsl_valid_4;
           __gen_e_acsl_i_5 = __gmpz_get_si((__e_acsl_mpz_struct const *)(__gen_e_acsl_i_4));
           __gen_e_acsl_valid_4 = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_5]),
-                                                sizeof(int));
+                                                sizeof(int),
+                                                (void *)(& buf[__gen_e_acsl_i_5]),
+                                                (void *)(& buf[__gen_e_acsl_i_5]));
           if (__gen_e_acsl_valid_4) ;
           else {
             __gen_e_acsl_forall_10 = 0;
diff --git a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c
index f8c75fba789b78fd8380b2d0c7df285d847b7886..292fda22f4898a6937e641620ea4cf92ac185572 100644
--- a/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c
+++ b/src/plugins/e-acsl/tests/gmp/oracle/gen_quantif2.c
@@ -621,7 +621,9 @@ int main(void)
           int __gen_e_acsl_valid;
           __gen_e_acsl_i_2 = __gmpz_get_si((__e_acsl_mpz_struct const *)(__gen_e_acsl_i));
           __gen_e_acsl_valid = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_2]),
-                                              sizeof(int));
+                                              sizeof(int),
+                                              (void *)(& buf[__gen_e_acsl_i_2]),
+                                              (void *)(& buf[__gen_e_acsl_i_2]));
           if (__gen_e_acsl_valid) ;
           else {
             __gen_e_acsl_forall_7 = 0;
@@ -677,7 +679,9 @@ int main(void)
           int __gen_e_acsl_valid_2;
           __gen_e_acsl_i_4 = __gmpz_get_si((__e_acsl_mpz_struct const *)(__gen_e_acsl_i_3));
           __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_4]),
-                                                sizeof(int));
+                                                sizeof(int),
+                                                (void *)(& buf[__gen_e_acsl_i_4]),
+                                                (void *)(& buf[__gen_e_acsl_i_4]));
           if (__gen_e_acsl_valid_2) ;
           else {
             __gen_e_acsl_forall_8 = 0;
@@ -733,7 +737,9 @@ int main(void)
           int __gen_e_acsl_valid_3;
           __gen_e_acsl_i_6 = __gmpz_get_si((__e_acsl_mpz_struct const *)(__gen_e_acsl_i_5));
           __gen_e_acsl_valid_3 = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_6]),
-                                                sizeof(int));
+                                                sizeof(int),
+                                                (void *)(& buf[__gen_e_acsl_i_6]),
+                                                (void *)(& buf[__gen_e_acsl_i_6]));
           if (__gen_e_acsl_valid_3) ;
           else {
             __gen_e_acsl_forall_9 = 0;
@@ -789,7 +795,9 @@ int main(void)
           int __gen_e_acsl_valid_4;
           __gen_e_acsl_i_8 = __gmpz_get_si((__e_acsl_mpz_struct const *)(__gen_e_acsl_i_7));
           __gen_e_acsl_valid_4 = __e_acsl_valid((void *)(& buf[__gen_e_acsl_i_8]),
-                                                sizeof(int));
+                                                sizeof(int),
+                                                (void *)(& buf[__gen_e_acsl_i_8]),
+                                                (void *)(& buf[__gen_e_acsl_i_8]));
           if (__gen_e_acsl_valid_4) ;
           else {
             __gen_e_acsl_forall_10 = 0;
diff --git a/src/plugins/e-acsl/tests/runtime/block_valid.c b/src/plugins/e-acsl/tests/runtime/block_valid.c
new file mode 100644
index 0000000000000000000000000000000000000000..16be7577c1028872881baebb97e579f0d6e47786
--- /dev/null
+++ b/src/plugins/e-acsl/tests/runtime/block_valid.c
@@ -0,0 +1,56 @@
+/* run.config
+  COMMENT: Check violations related to accessing an allocated memory block
+  COMMENT: through a pointer to another block
+*/
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#define ADDROF(_a) ((uintptr_t)_a)
+
+int A = 1,
+    B = 2,
+    C = 3;
+
+int main(int argc, char **argv) {
+  int *p = NULL,
+      *q = NULL;
+
+  int a = 1,
+      b = 2,
+      c = 3;
+
+  p = &b;
+  /*@assert \valid(p); */
+  /* `p` points to `b`, `p+1` accesses either `a` or `c` */
+  /*@assert ! \valid(p+1); */
+
+  p = &B;
+  /*@assert \valid(p); */
+  /* `p` points to `B`, `p+1` accesses either `A` or `C` */
+  /*@assert ! \valid(p+1); */
+
+  char *pmin = (char*)malloc(sizeof(int));
+  char *pmax = (char*)malloc(sizeof(int));
+
+  /* Since `pmin` is allocated before `pmax` it is likely that the start
+   * address of `pmin` is less than the start address of `pmax`, still,
+   * just in case, make sure it is true and swap the addresses otherwise. */
+  if (ADDROF(pmin) > ADDROF(pmax)) {
+    char *t = pmin;
+    pmin = pmax;
+    pmax = t;
+  }
+
+  *pmin = 'P';
+  *pmax = 'L';
+
+  int diff = pmax - pmin;
+  /*@assert \valid(pmin); */
+  /*@assert \valid(pmax); */
+  /* Access `pmax` through `pmin` */
+  /*@assert ! \valid(pmin + diff); */
+  /* Access `pmin` through `pmax` */
+  /*@assert ! \valid(pmax - diff); */
+  return 0;
+}
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/block_valid.err.oracle b/src/plugins/e-acsl/tests/runtime/oracle/block_valid.err.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/block_valid.res.oracle b/src/plugins/e-acsl/tests/runtime/oracle/block_valid.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..f102d73fa2acd8532fc8b3156a5b88d60a33e687
--- /dev/null
+++ b/src/plugins/e-acsl/tests/runtime/oracle/block_valid.res.oracle
@@ -0,0 +1,8 @@
+[e-acsl] beginning translation.
+[e-acsl] translation done in project "e-acsl".
+FRAMAC_SHARE/e-acsl/e_acsl.h:43:[value] warning: function __e_acsl_assert: precondition got status unknown.
+tests/runtime/block_valid.c:39:[value] warning: pointer comparison. assert \pointer_comparable((void *)pmin, (void *)pmax);
+tests/runtime/block_valid.c:45:[value] warning: out of bounds write. assert \valid(pmin);
+tests/runtime/block_valid.c:46:[value] warning: out of bounds write. assert \valid(pmax);
+tests/runtime/block_valid.c:52:[value] warning: assertion got status unknown.
+tests/runtime/block_valid.c:54:[value] warning: assertion got status unknown.
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_block_valid.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_block_valid.c
new file mode 100644
index 0000000000000000000000000000000000000000..647000e85831e18a450745271bf223edacf7c23a
--- /dev/null
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_block_valid.c
@@ -0,0 +1,163 @@
+/* Generated by Frama-C */
+#include "stdlib.h"
+int A = 1;
+int B = 2;
+int C = 3;
+void __e_acsl_globals_init(void)
+{
+  __e_acsl_store_block((void *)(& B),(size_t)4);
+  __e_acsl_full_init((void *)(& B));
+  return;
+}
+
+int main(int argc, char **argv)
+{
+  int __retres;
+  __e_acsl_memory_init(& argc,& argv,(size_t)8);
+  __e_acsl_globals_init();
+  int *p = (int *)0;
+  __e_acsl_store_block((void *)(& p),(size_t)8);
+  __e_acsl_full_init((void *)(& p));
+  int *q = (int *)0;
+  int a = 1;
+  int b = 2;
+  __e_acsl_store_block((void *)(& b),(size_t)4);
+  __e_acsl_full_init((void *)(& b));
+  int c = 3;
+  __e_acsl_full_init((void *)(& p));
+  p = & b;
+  /*@ assert \valid(p); */
+  {
+    int __gen_e_acsl_initialized;
+    int __gen_e_acsl_and;
+    __gen_e_acsl_initialized = __e_acsl_initialized((void *)(& p),
+                                                    sizeof(int *));
+    if (__gen_e_acsl_initialized) {
+      int __gen_e_acsl_valid;
+      __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                          (void *)(& p));
+      __gen_e_acsl_and = __gen_e_acsl_valid;
+    }
+    else __gen_e_acsl_and = 0;
+    __e_acsl_assert(__gen_e_acsl_and,(char *)"Assertion",(char *)"main",
+                    (char *)"\\valid(p)",24);
+  }
+  /*@ assert ¬\valid(p + 1); */
+  {
+    int __gen_e_acsl_valid_2;
+    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(p + 1),sizeof(int),
+                                          (void *)p,(void *)(& p));
+    __e_acsl_assert(! __gen_e_acsl_valid_2,(char *)"Assertion",
+                    (char *)"main",(char *)"!\\valid(p + 1)",26);
+  }
+  __e_acsl_full_init((void *)(& p));
+  p = & B;
+  /*@ assert \valid(p); */
+  {
+    int __gen_e_acsl_initialized_2;
+    int __gen_e_acsl_and_2;
+    __gen_e_acsl_initialized_2 = __e_acsl_initialized((void *)(& p),
+                                                      sizeof(int *));
+    if (__gen_e_acsl_initialized_2) {
+      int __gen_e_acsl_valid_3;
+      __gen_e_acsl_valid_3 = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                            (void *)(& p));
+      __gen_e_acsl_and_2 = __gen_e_acsl_valid_3;
+    }
+    else __gen_e_acsl_and_2 = 0;
+    __e_acsl_assert(__gen_e_acsl_and_2,(char *)"Assertion",(char *)"main",
+                    (char *)"\\valid(p)",29);
+  }
+  /*@ assert ¬\valid(p + 1); */
+  {
+    int __gen_e_acsl_valid_4;
+    __gen_e_acsl_valid_4 = __e_acsl_valid((void *)(p + 1),sizeof(int),
+                                          (void *)p,(void *)(& p));
+    __e_acsl_assert(! __gen_e_acsl_valid_4,(char *)"Assertion",
+                    (char *)"main",(char *)"!\\valid(p + 1)",31);
+  }
+  char *pmin = malloc(sizeof(int));
+  __e_acsl_store_block((void *)(& pmin),(size_t)8);
+  __e_acsl_full_init((void *)(& pmin));
+  char *pmax = malloc(sizeof(int));
+  __e_acsl_store_block((void *)(& pmax),(size_t)8);
+  __e_acsl_full_init((void *)(& pmax));
+  /*@ assert
+      Value: ptr_comparison: \pointer_comparable((void *)pmin, (void *)pmax);
+  */
+  if ((unsigned long)pmin > (unsigned long)pmax) {
+    char *t = pmin;
+    __e_acsl_store_block((void *)(& t),(size_t)8);
+    __e_acsl_full_init((void *)(& t));
+    __e_acsl_full_init((void *)(& pmin));
+    pmin = pmax;
+    __e_acsl_full_init((void *)(& pmax));
+    pmax = t;
+    __e_acsl_delete_block((void *)(& t));
+  }
+  __e_acsl_initialize((void *)pmin,sizeof(char));
+  /*@ assert Value: mem_access: \valid(pmin); */
+  *pmin = (char)'P';
+  __e_acsl_initialize((void *)pmax,sizeof(char));
+  /*@ assert Value: mem_access: \valid(pmax); */
+  *pmax = (char)'L';
+  int diff = (int)(pmax - pmin);
+  /*@ assert \valid(pmin); */
+  {
+    int __gen_e_acsl_initialized_3;
+    int __gen_e_acsl_and_3;
+    __gen_e_acsl_initialized_3 = __e_acsl_initialized((void *)(& pmin),
+                                                      sizeof(char *));
+    if (__gen_e_acsl_initialized_3) {
+      int __gen_e_acsl_valid_5;
+      __gen_e_acsl_valid_5 = __e_acsl_valid((void *)pmin,sizeof(char),
+                                            (void *)pmin,(void *)(& pmin));
+      __gen_e_acsl_and_3 = __gen_e_acsl_valid_5;
+    }
+    else __gen_e_acsl_and_3 = 0;
+    __e_acsl_assert(__gen_e_acsl_and_3,(char *)"Assertion",(char *)"main",
+                    (char *)"\\valid(pmin)",49);
+  }
+  /*@ assert \valid(pmax); */
+  {
+    int __gen_e_acsl_initialized_4;
+    int __gen_e_acsl_and_4;
+    __gen_e_acsl_initialized_4 = __e_acsl_initialized((void *)(& pmax),
+                                                      sizeof(char *));
+    if (__gen_e_acsl_initialized_4) {
+      int __gen_e_acsl_valid_6;
+      __gen_e_acsl_valid_6 = __e_acsl_valid((void *)pmax,sizeof(char),
+                                            (void *)pmax,(void *)(& pmax));
+      __gen_e_acsl_and_4 = __gen_e_acsl_valid_6;
+    }
+    else __gen_e_acsl_and_4 = 0;
+    __e_acsl_assert(__gen_e_acsl_and_4,(char *)"Assertion",(char *)"main",
+                    (char *)"\\valid(pmax)",50);
+  }
+  /*@ assert ¬\valid(pmin + diff); */
+  {
+    int __gen_e_acsl_valid_7;
+    __gen_e_acsl_valid_7 = __e_acsl_valid((void *)(pmin + diff),sizeof(char),
+                                          (void *)pmin,(void *)(& pmin));
+    __e_acsl_assert(! __gen_e_acsl_valid_7,(char *)"Assertion",
+                    (char *)"main",(char *)"!\\valid(pmin + diff)",52);
+  }
+  /*@ assert ¬\valid(pmax - diff); */
+  {
+    int __gen_e_acsl_valid_8;
+    __gen_e_acsl_valid_8 = __e_acsl_valid((void *)(pmax - diff),sizeof(char),
+                                          (void *)pmax,(void *)(& pmax));
+    __e_acsl_assert(! __gen_e_acsl_valid_8,(char *)"Assertion",
+                    (char *)"main",(char *)"!\\valid(pmax - diff)",54);
+  }
+  __retres = 0;
+  __e_acsl_delete_block((void *)(& B));
+  __e_acsl_delete_block((void *)(& pmax));
+  __e_acsl_delete_block((void *)(& pmin));
+  __e_acsl_delete_block((void *)(& b));
+  __e_acsl_delete_block((void *)(& p));
+  __e_acsl_memory_clean();
+  return __retres;
+}
+
+
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_bypassed_var.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_bypassed_var.c
index 764f19cd894ff68db95cb5b0a205d84d6071ffe1..7787974a78645a3f0769e05b917875be64023ed0 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_bypassed_var.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_bypassed_var.c
@@ -15,7 +15,8 @@ int main(int argc, char const **argv)
     /*@ assert \valid(&p); */
     {
       int __gen_e_acsl_valid;
-      __gen_e_acsl_valid = __e_acsl_valid((void *)(& p),sizeof(int *));
+      __gen_e_acsl_valid = __e_acsl_valid((void *)(& p),sizeof(int *),
+                                          (void *)(& p),(void *)(& p));
       __e_acsl_assert(__gen_e_acsl_valid,(char *)"Assertion",(char *)"main",
                       (char *)"\\valid(&p)",13);
       __e_acsl_delete_block((void *)(& p));
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_compound_initializers.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_compound_initializers.c
index a16228735c86893207795bdcad39784861c62f2c..79bcb004e84c6ae14ff66c70a9327721f7b5fd89 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_compound_initializers.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_compound_initializers.c
@@ -24,24 +24,24 @@ void __e_acsl_globals_init(void)
   __gen_e_acsl_literal_string_3 = "ZZ";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_3,sizeof("ZZ"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_3);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_3);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_3);
   __gen_e_acsl_literal_string = "YY";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,sizeof("YY"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   __gen_e_acsl_literal_string_2 = "XX";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_2,sizeof("XX"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_2);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_2);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_2);
   __gen_e_acsl_literal_string_4 = "Second";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_4,
                        sizeof("Second"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_4);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_4);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_4);
   __gen_e_acsl_literal_string_5 = "First";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_5,sizeof("First"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_5);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_5);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_5);
   __e_acsl_store_block((void *)(_G),(size_t)32);
   __e_acsl_full_init((void *)(& _G));
   __e_acsl_store_block((void *)(& _E),(size_t)4);
@@ -67,7 +67,8 @@ int main(int argc, char **argv)
   /*@ assert \valid((char **)_A); */
   {
     int __gen_e_acsl_valid;
-    __gen_e_acsl_valid = __e_acsl_valid((void *)(_A),sizeof(char *));
+    __gen_e_acsl_valid = __e_acsl_valid((void *)(_A),sizeof(char *),
+                                        (void *)(_A),(void *)(_A));
     __e_acsl_assert(__gen_e_acsl_valid,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid((char **)_A)",33);
   }
@@ -80,7 +81,9 @@ int main(int argc, char **argv)
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid_read;
       __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)_A[0],
-                                                    sizeof(char));
+                                                    sizeof(char),
+                                                    (void *)_A[0],
+                                                    (void *)(_A));
       __gen_e_acsl_and = __gen_e_acsl_valid_read;
     }
     else __gen_e_acsl_and = 0;
@@ -96,7 +99,9 @@ int main(int argc, char **argv)
     if (__gen_e_acsl_initialized_2) {
       int __gen_e_acsl_valid_read_2;
       __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)_A[1],
-                                                      sizeof(char));
+                                                      sizeof(char),
+                                                      (void *)_A[1],
+                                                      (void *)(& _A[1]));
       __gen_e_acsl_and_2 = __gen_e_acsl_valid_read_2;
     }
     else __gen_e_acsl_and_2 = 0;
@@ -106,35 +111,41 @@ int main(int argc, char **argv)
   /*@ assert \valid_read(_B); */
   {
     int __gen_e_acsl_valid_read_3;
-    __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)_B,sizeof(char));
+    __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)_B,sizeof(char),
+                                                    (void *)_B,
+                                                    (void *)(& _B));
     __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"Assertion",
                     (char *)"main",(char *)"\\valid_read(_B)",36);
   }
   /*@ assert \valid(&_C); */
   {
     int __gen_e_acsl_valid_2;
-    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& _C),sizeof(char *));
+    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& _C),sizeof(char *),
+                                          (void *)(& _C),(void *)(& _C));
     __e_acsl_assert(__gen_e_acsl_valid_2,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(&_C)",37);
   }
   /*@ assert \valid((int *)_D); */
   {
     int __gen_e_acsl_valid_3;
-    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)(_D),sizeof(int));
+    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)(_D),sizeof(int),
+                                          (void *)(_D),(void *)(_D));
     __e_acsl_assert(__gen_e_acsl_valid_3,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid((int *)_D)",38);
   }
   /*@ assert \valid(&_E); */
   {
     int __gen_e_acsl_valid_4;
-    __gen_e_acsl_valid_4 = __e_acsl_valid((void *)(& _E),sizeof(int));
+    __gen_e_acsl_valid_4 = __e_acsl_valid((void *)(& _E),sizeof(int),
+                                          (void *)(& _E),(void *)(& _E));
     __e_acsl_assert(__gen_e_acsl_valid_4,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(&_E)",39);
   }
   /*@ assert \valid(&_F); */
   {
     int __gen_e_acsl_valid_5;
-    __gen_e_acsl_valid_5 = __e_acsl_valid((void *)(& _F),sizeof(int));
+    __gen_e_acsl_valid_5 = __e_acsl_valid((void *)(& _F),sizeof(int),
+                                          (void *)(& _F),(void *)(& _F));
     __e_acsl_assert(__gen_e_acsl_valid_5,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(&_F)",40);
   }
@@ -145,7 +156,8 @@ int main(int argc, char **argv)
   {
     int __gen_e_acsl_valid_6;
     __gen_e_acsl_valid_6 = __e_acsl_valid((void *)(& _G),
-                                          sizeof(struct ST [2]));
+                                          sizeof(struct ST [2]),
+                                          (void *)(& _G),(void *)(& _G));
     __e_acsl_assert(__gen_e_acsl_valid_6,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(&_G)",42);
   }
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_ctype_macros.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_ctype_macros.c
index 951c2559308ad3597666381bd03d960a5b65b43d..aaed0eb2d73a75f3af1620603b65fe959701555f 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_ctype_macros.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_ctype_macros.c
@@ -21,7 +21,8 @@ int main(int argc, char const **argv)
                                                     sizeof(char *));
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid;
-      __gen_e_acsl_valid = __e_acsl_valid((void *)d,sizeof(char));
+      __gen_e_acsl_valid = __e_acsl_valid((void *)d,sizeof(char),(void *)d,
+                                          (void *)(& d));
       __gen_e_acsl_and = __gen_e_acsl_valid;
     }
     else __gen_e_acsl_and = 0;
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_early_exit.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_early_exit.c
index 780fc3a88c485032c5b28a14fc41c147ebdec8d3..3f1e85b9d1564ccab6b073ed178b435cc1a9ac7d 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_early_exit.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_early_exit.c
@@ -19,7 +19,8 @@ int goto_bts(void)
                                                       sizeof(int *));
       if (__gen_e_acsl_initialized) {
         int __gen_e_acsl_valid;
-        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                            (void *)(& p));
         __gen_e_acsl_and = __gen_e_acsl_valid;
       }
       else __gen_e_acsl_and = 0;
@@ -40,7 +41,8 @@ int goto_bts(void)
       if (__gen_e_acsl_initialized_2) {
         int __gen_e_acsl_valid_2;
         /*@ assert Value: dangling_pointer: ¬\dangling(&p); */
-        __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(int),
+                                              (void *)p,(void *)(& p));
         __gen_e_acsl_and_2 = __gen_e_acsl_valid_2;
       }
       else __gen_e_acsl_and_2 = 0;
@@ -104,7 +106,8 @@ int goto_valid(void)
                                                         sizeof(int *));
         if (__gen_e_acsl_initialized) {
           int __gen_e_acsl_valid;
-          __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+          __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),
+                                              (void *)p,(void *)(& p));
           __gen_e_acsl_and = __gen_e_acsl_valid;
         }
         else __gen_e_acsl_and = 0;
@@ -120,7 +123,8 @@ int goto_valid(void)
         if (__gen_e_acsl_initialized_2) {
           int __gen_e_acsl_valid_2;
           /*@ assert Value: dangling_pointer: ¬\dangling(&q); */
-          __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int));
+          __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int),
+                                                (void *)q,(void *)(& q));
           __gen_e_acsl_and_2 = __gen_e_acsl_valid_2;
         }
         else __gen_e_acsl_and_2 = 0;
@@ -136,7 +140,8 @@ int goto_valid(void)
         if (__gen_e_acsl_initialized_3) {
           int __gen_e_acsl_valid_3;
           /*@ assert Value: dangling_pointer: ¬\dangling(&r); */
-          __gen_e_acsl_valid_3 = __e_acsl_valid((void *)r,sizeof(int));
+          __gen_e_acsl_valid_3 = __e_acsl_valid((void *)r,sizeof(int),
+                                                (void *)r,(void *)(& r));
           __gen_e_acsl_and_3 = __gen_e_acsl_valid_3;
         }
         else __gen_e_acsl_and_3 = 0;
@@ -165,7 +170,8 @@ int goto_valid(void)
       if (__gen_e_acsl_initialized_4) {
         int __gen_e_acsl_valid_4;
         /*@ assert Value: dangling_pointer: ¬\dangling(&p); */
-        __gen_e_acsl_valid_4 = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid_4 = __e_acsl_valid((void *)p,sizeof(int),
+                                              (void *)p,(void *)(& p));
         __gen_e_acsl_and_4 = __gen_e_acsl_valid_4;
       }
       else __gen_e_acsl_and_4 = 0;
@@ -181,7 +187,8 @@ int goto_valid(void)
       if (__gen_e_acsl_initialized_5) {
         int __gen_e_acsl_valid_5;
         /*@ assert Value: dangling_pointer: ¬\dangling(&q); */
-        __gen_e_acsl_valid_5 = __e_acsl_valid((void *)q,sizeof(int));
+        __gen_e_acsl_valid_5 = __e_acsl_valid((void *)q,sizeof(int),
+                                              (void *)q,(void *)(& q));
         __gen_e_acsl_and_5 = __gen_e_acsl_valid_5;
       }
       else __gen_e_acsl_and_5 = 0;
@@ -197,7 +204,8 @@ int goto_valid(void)
       if (__gen_e_acsl_initialized_6) {
         int __gen_e_acsl_valid_6;
         /*@ assert Value: dangling_pointer: ¬\dangling(&r); */
-        __gen_e_acsl_valid_6 = __e_acsl_valid((void *)r,sizeof(int));
+        __gen_e_acsl_valid_6 = __e_acsl_valid((void *)r,sizeof(int),
+                                              (void *)r,(void *)(& r));
         __gen_e_acsl_and_6 = __gen_e_acsl_valid_6;
       }
       else __gen_e_acsl_and_6 = 0;
@@ -247,7 +255,8 @@ int switch_valid(void)
                                                           sizeof(int *));
           if (__gen_e_acsl_initialized) {
             int __gen_e_acsl_valid;
-            __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+            __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),
+                                                (void *)p,(void *)(& p));
             __gen_e_acsl_and = __gen_e_acsl_valid;
           }
           else __gen_e_acsl_and = 0;
@@ -262,7 +271,8 @@ int switch_valid(void)
                                                             sizeof(int *));
           if (__gen_e_acsl_initialized_2) {
             int __gen_e_acsl_valid_2;
-            __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int));
+            __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int),
+                                                  (void *)q,(void *)(& q));
             __gen_e_acsl_and_2 = __gen_e_acsl_valid_2;
           }
           else __gen_e_acsl_and_2 = 0;
@@ -277,7 +287,8 @@ int switch_valid(void)
                                                             sizeof(int *));
           if (__gen_e_acsl_initialized_3) {
             int __gen_e_acsl_valid_3;
-            __gen_e_acsl_valid_3 = __e_acsl_valid((void *)s,sizeof(int));
+            __gen_e_acsl_valid_3 = __e_acsl_valid((void *)s,sizeof(int),
+                                                  (void *)s,(void *)(& s));
             __gen_e_acsl_and_3 = __gen_e_acsl_valid_3;
           }
           else __gen_e_acsl_and_3 = 0;
@@ -309,7 +320,8 @@ int switch_valid(void)
     if (__gen_e_acsl_initialized_4) {
       int __gen_e_acsl_valid_4;
       /*@ assert Value: dangling_pointer: ¬\dangling(&q); */
-      __gen_e_acsl_valid_4 = __e_acsl_valid((void *)q,sizeof(int));
+      __gen_e_acsl_valid_4 = __e_acsl_valid((void *)q,sizeof(int),(void *)q,
+                                            (void *)(& q));
       __gen_e_acsl_and_4 = __gen_e_acsl_valid_4;
     }
     else __gen_e_acsl_and_4 = 0;
@@ -325,7 +337,8 @@ int switch_valid(void)
     if (__gen_e_acsl_initialized_5) {
       int __gen_e_acsl_valid_5;
       /*@ assert Value: dangling_pointer: ¬\dangling(&p); */
-      __gen_e_acsl_valid_5 = __e_acsl_valid((void *)p,sizeof(int));
+      __gen_e_acsl_valid_5 = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                            (void *)(& p));
       __gen_e_acsl_and_5 = __gen_e_acsl_valid_5;
     }
     else __gen_e_acsl_and_5 = 0;
@@ -340,7 +353,8 @@ int switch_valid(void)
                                                       sizeof(int *));
     if (__gen_e_acsl_initialized_6) {
       int __gen_e_acsl_valid_6;
-      __gen_e_acsl_valid_6 = __e_acsl_valid((void *)s,sizeof(int));
+      __gen_e_acsl_valid_6 = __e_acsl_valid((void *)s,sizeof(int),(void *)s,
+                                            (void *)(& s));
       __gen_e_acsl_and_6 = __gen_e_acsl_valid_6;
     }
     else __gen_e_acsl_and_6 = 0;
@@ -394,7 +408,8 @@ int while_valid(void)
                                                             sizeof(int *));
             if (__gen_e_acsl_initialized) {
               int __gen_e_acsl_valid;
-              __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+              __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),
+                                                  (void *)p,(void *)(& p));
               __gen_e_acsl_and = __gen_e_acsl_valid;
             }
             else __gen_e_acsl_and = 0;
@@ -409,7 +424,8 @@ int while_valid(void)
                                                               sizeof(int *));
             if (__gen_e_acsl_initialized_2) {
               int __gen_e_acsl_valid_2;
-              __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int));
+              __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int),
+                                                    (void *)q,(void *)(& q));
               __gen_e_acsl_and_2 = __gen_e_acsl_valid_2;
             }
             else __gen_e_acsl_and_2 = 0;
@@ -424,7 +440,8 @@ int while_valid(void)
                                                               sizeof(int *));
             if (__gen_e_acsl_initialized_3) {
               int __gen_e_acsl_valid_3;
-              __gen_e_acsl_valid_3 = __e_acsl_valid((void *)r,sizeof(int));
+              __gen_e_acsl_valid_3 = __e_acsl_valid((void *)r,sizeof(int),
+                                                    (void *)r,(void *)(& r));
               __gen_e_acsl_and_3 = __gen_e_acsl_valid_3;
             }
             else __gen_e_acsl_and_3 = 0;
@@ -451,7 +468,8 @@ int while_valid(void)
         int __gen_e_acsl_valid_4;
         /*@ assert Value: initialisation: \initialized(&p); */
         /*@ assert Value: dangling_pointer: ¬\dangling(&p); */
-        __gen_e_acsl_valid_4 = __e_acsl_valid((void *)p,sizeof(int));
+        __gen_e_acsl_valid_4 = __e_acsl_valid((void *)p,sizeof(int),
+                                              (void *)p,(void *)(& p));
         __gen_e_acsl_and_4 = __gen_e_acsl_valid_4;
       }
       else __gen_e_acsl_and_4 = 0;
@@ -468,7 +486,8 @@ int while_valid(void)
         int __gen_e_acsl_valid_5;
         /*@ assert Value: initialisation: \initialized(&q); */
         /*@ assert Value: dangling_pointer: ¬\dangling(&q); */
-        __gen_e_acsl_valid_5 = __e_acsl_valid((void *)q,sizeof(int));
+        __gen_e_acsl_valid_5 = __e_acsl_valid((void *)q,sizeof(int),
+                                              (void *)q,(void *)(& q));
         __gen_e_acsl_and_5 = __gen_e_acsl_valid_5;
       }
       else __gen_e_acsl_and_5 = 0;
@@ -483,7 +502,8 @@ int while_valid(void)
                                                         sizeof(int *));
       if (__gen_e_acsl_initialized_6) {
         int __gen_e_acsl_valid_6;
-        __gen_e_acsl_valid_6 = __e_acsl_valid((void *)r,sizeof(int));
+        __gen_e_acsl_valid_6 = __e_acsl_valid((void *)r,sizeof(int),
+                                              (void *)r,(void *)(& r));
         __gen_e_acsl_and_6 = __gen_e_acsl_valid_6;
       }
       else __gen_e_acsl_and_6 = 0;
@@ -523,7 +543,8 @@ void continue_valid(void)
                                                         sizeof(int *));
         if (__gen_e_acsl_initialized) {
           int __gen_e_acsl_valid;
-          __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+          __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),
+                                              (void *)p,(void *)(& p));
           __gen_e_acsl_and = __gen_e_acsl_valid;
         }
         else __gen_e_acsl_and = 0;
@@ -538,7 +559,8 @@ void continue_valid(void)
                                                           sizeof(int *));
         if (__gen_e_acsl_initialized_2) {
           int __gen_e_acsl_valid_2;
-          __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int));
+          __gen_e_acsl_valid_2 = __e_acsl_valid((void *)q,sizeof(int),
+                                                (void *)q,(void *)(& q));
           __gen_e_acsl_and_2 = __gen_e_acsl_valid_2;
         }
         else __gen_e_acsl_and_2 = 0;
@@ -558,7 +580,8 @@ void continue_valid(void)
                                                           sizeof(int *));
         if (__gen_e_acsl_initialized_3) {
           int __gen_e_acsl_valid_3;
-          __gen_e_acsl_valid_3 = __e_acsl_valid((void *)p,sizeof(int));
+          __gen_e_acsl_valid_3 = __e_acsl_valid((void *)p,sizeof(int),
+                                                (void *)p,(void *)(& p));
           __gen_e_acsl_and_3 = __gen_e_acsl_valid_3;
         }
         else __gen_e_acsl_and_3 = 0;
@@ -573,7 +596,8 @@ void continue_valid(void)
                                                           sizeof(int *));
         if (__gen_e_acsl_initialized_4) {
           int __gen_e_acsl_valid_4;
-          __gen_e_acsl_valid_4 = __e_acsl_valid((void *)q,sizeof(int));
+          __gen_e_acsl_valid_4 = __e_acsl_valid((void *)q,sizeof(int),
+                                                (void *)q,(void *)(& q));
           __gen_e_acsl_and_4 = __gen_e_acsl_valid_4;
         }
         else __gen_e_acsl_and_4 = 0;
@@ -594,7 +618,8 @@ void continue_valid(void)
                                                             sizeof(int *));
           if (__gen_e_acsl_initialized_5) {
             int __gen_e_acsl_valid_5;
-            __gen_e_acsl_valid_5 = __e_acsl_valid((void *)p,sizeof(int));
+            __gen_e_acsl_valid_5 = __e_acsl_valid((void *)p,sizeof(int),
+                                                  (void *)p,(void *)(& p));
             __gen_e_acsl_and_5 = __gen_e_acsl_valid_5;
           }
           else __gen_e_acsl_and_5 = 0;
@@ -609,7 +634,8 @@ void continue_valid(void)
                                                             sizeof(int *));
           if (__gen_e_acsl_initialized_6) {
             int __gen_e_acsl_valid_6;
-            __gen_e_acsl_valid_6 = __e_acsl_valid((void *)q,sizeof(int));
+            __gen_e_acsl_valid_6 = __e_acsl_valid((void *)q,sizeof(int),
+                                                  (void *)q,(void *)(& q));
             __gen_e_acsl_and_6 = __gen_e_acsl_valid_6;
           }
           else __gen_e_acsl_and_6 = 0;
@@ -636,7 +662,8 @@ void continue_valid(void)
                                                       sizeof(int *));
     if (__gen_e_acsl_initialized_7) {
       int __gen_e_acsl_valid_7;
-      __gen_e_acsl_valid_7 = __e_acsl_valid((void *)p,sizeof(int));
+      __gen_e_acsl_valid_7 = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                            (void *)(& p));
       __gen_e_acsl_and_7 = __gen_e_acsl_valid_7;
     }
     else __gen_e_acsl_and_7 = 0;
@@ -651,7 +678,8 @@ void continue_valid(void)
                                                       sizeof(int *));
     if (__gen_e_acsl_initialized_8) {
       int __gen_e_acsl_valid_8;
-      __gen_e_acsl_valid_8 = __e_acsl_valid((void *)q,sizeof(int));
+      __gen_e_acsl_valid_8 = __e_acsl_valid((void *)q,sizeof(int),(void *)q,
+                                            (void *)(& q));
       __gen_e_acsl_and_8 = __gen_e_acsl_valid_8;
     }
     else __gen_e_acsl_and_8 = 0;
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_errno.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_errno.c
index 9e580cdb8c410429dc4d9da2b4fb5c6a0cbdbbe2..789e410437316560413926af468f98ff0ab50dd9 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_errno.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_errno.c
@@ -25,7 +25,8 @@ int main(int argc, char const **argv)
                                                     sizeof(int *));
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid;
-      __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int));
+      __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(int),(void *)p,
+                                          (void *)(& p));
       __gen_e_acsl_and = __gen_e_acsl_valid;
     }
     else __gen_e_acsl_and = 0;
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_literal_string.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_literal_string.c
index 0938ccde373718177bd3a8d9d140358c94a5b134..54dc8baee650a7c57447027315d087b70c139350 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_literal_string.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_literal_string.c
@@ -16,7 +16,8 @@ void f(void)
   {
     int __gen_e_acsl_valid_read;
     __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(T + G),
-                                                  sizeof(char));
+                                                  sizeof(char),(void *)T,
+                                                  (void *)(& T));
     __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"f",
                     (char *)"mem_access: \\valid_read(T + G)",11);
     __e_acsl_assert(*(T + G) == 'b',(char *)"Assertion",(char *)"f",
@@ -39,28 +40,28 @@ void __e_acsl_globals_init(void)
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_6,
                        sizeof("the dog and the cat"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_6);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_6);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_6);
   __gen_e_acsl_literal_string_5 = "the cat";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_5,
                        sizeof("the cat"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_5);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_5);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_5);
   __gen_e_acsl_literal_string = "ss";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,sizeof("ss"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   __gen_e_acsl_literal_string_4 = "foo2";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_4,sizeof("foo2"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_4);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_4);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_4);
   __gen_e_acsl_literal_string_3 = "foo";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_3,sizeof("foo"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_3);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_3);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_3);
   __gen_e_acsl_literal_string_2 = "bar";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_2,sizeof("bar"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_2);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_2);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_2);
   __e_acsl_store_block((void *)(& l_str),(size_t)8);
   __e_acsl_full_init((void *)(& l_str));
   __e_acsl_store_block((void *)(& s_str),(size_t)8);
@@ -86,7 +87,8 @@ int main(void)
   {
     int __gen_e_acsl_valid_read;
     __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(S + G2),
-                                                  sizeof(char));
+                                                  sizeof(char),(void *)S,
+                                                  (void *)(& S));
     __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"main",
                     (char *)"mem_access: \\valid_read(S + G2)",25);
     __e_acsl_assert(*(S + G2) == 'o',(char *)"Assertion",(char *)"main",
@@ -102,7 +104,9 @@ int main(void)
   /*@ assert \valid_read(S2); */
   {
     int __gen_e_acsl_valid_read_2;
-    __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)S2,sizeof(char));
+    __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)S2,sizeof(char),
+                                                    (void *)S2,
+                                                    (void *)(& S2));
     __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"Assertion",
                     (char *)"main",(char *)"\\valid_read(S2)",27);
   }
@@ -114,7 +118,8 @@ int main(void)
                                                       sizeof(char *));
     if (__gen_e_acsl_initialized_2) {
       int __gen_e_acsl_valid;
-      __gen_e_acsl_valid = __e_acsl_valid((void *)SS,sizeof(char));
+      __gen_e_acsl_valid = __e_acsl_valid((void *)SS,sizeof(char),(void *)SS,
+                                          (void *)(& SS));
       __gen_e_acsl_and = __gen_e_acsl_valid;
     }
     else __gen_e_acsl_and = 0;
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_local_goto.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_local_goto.c
index f5a71822eb517779399c79fb801f5cc3f2f2211e..9e517c9ce5af02cd174e8b4a87c129e9c4b01516 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_local_goto.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_local_goto.c
@@ -11,19 +11,19 @@ void __e_acsl_globals_init(void)
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string,
                        sizeof("t is %d, going to %s\n"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string);
   __gen_e_acsl_literal_string_3 = "UP";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_3,sizeof("UP"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_3);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_3);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_3);
   __gen_e_acsl_literal_string_2 = "RET";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_2,sizeof("RET"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_2);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_2);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_2);
   __gen_e_acsl_literal_string_4 = "AGAIN";
   __e_acsl_store_block((void *)__gen_e_acsl_literal_string_4,sizeof("AGAIN"));
   __e_acsl_full_init((void *)__gen_e_acsl_literal_string_4);
-  __e_acsl_readonly((void *)__gen_e_acsl_literal_string_4);
+  __e_acsl_mark_readonly((void *)__gen_e_acsl_literal_string_4);
   return;
 }
 
@@ -48,7 +48,8 @@ int main(int argc, char const **argv)
       /*@ assert \valid(&a); */
       {
         int __gen_e_acsl_valid;
-        __gen_e_acsl_valid = __e_acsl_valid((void *)(& a),sizeof(int));
+        __gen_e_acsl_valid = __e_acsl_valid((void *)(& a),sizeof(int),
+                                            (void *)(& a),(void *)(& a));
         __e_acsl_assert(__gen_e_acsl_valid,(char *)"Assertion",
                         (char *)"main",(char *)"\\valid(&a)",25);
       }
@@ -65,7 +66,8 @@ int main(int argc, char const **argv)
       /*@ assert \valid(&b); */
       {
         int __gen_e_acsl_valid_2;
-        __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& b),sizeof(int));
+        __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& b),sizeof(int),
+                                              (void *)(& b),(void *)(& b));
         __e_acsl_assert(__gen_e_acsl_valid_2,(char *)"Assertion",
                         (char *)"main",(char *)"\\valid(&b)",36);
       }
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_mainargs.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_mainargs.c
index 44028547cfb0109025238e8e249f6313f306f36a..f0a7e6b8479128adb4c0d2fe5d0290b0cf167f69 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_mainargs.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_mainargs.c
@@ -11,14 +11,16 @@ int main(int argc, char **argv)
     int __gen_e_acsl_valid;
     __e_acsl_store_block((void *)(& argv),(size_t)8);
     __e_acsl_store_block((void *)(& argc),(size_t)4);
-    __gen_e_acsl_valid = __e_acsl_valid((void *)(& argc),sizeof(int));
+    __gen_e_acsl_valid = __e_acsl_valid((void *)(& argc),sizeof(int),
+                                        (void *)(& argc),(void *)(& argc));
     __e_acsl_assert(__gen_e_acsl_valid,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(&argc)",10);
   }
   /*@ assert \valid(&argv); */
   {
     int __gen_e_acsl_valid_2;
-    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& argv),sizeof(char **));
+    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)(& argv),sizeof(char **),
+                                          (void *)(& argv),(void *)(& argv));
     __e_acsl_assert(__gen_e_acsl_valid_2,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(&argv)",11);
   }
@@ -33,7 +35,8 @@ int main(int argc, char **argv)
       {
         int __gen_e_acsl_valid_3;
         __gen_e_acsl_valid_3 = __e_acsl_valid((void *)(argv + __gen_e_acsl_k),
-                                              sizeof(char *));
+                                              sizeof(char *),(void *)argv,
+                                              (void *)(& argv));
         if (__gen_e_acsl_valid_3) ;
         else {
           __gen_e_acsl_forall = 0;
@@ -68,7 +71,9 @@ int main(int argc, char **argv)
   {
     int __gen_e_acsl_valid_read;
     __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)(argv + argc),
-                                                  sizeof(char *));
+                                                  sizeof(char *),
+                                                  (void *)argv,
+                                                  (void *)(& argv));
     __e_acsl_assert(__gen_e_acsl_valid_read,(char *)"RTE",(char *)"main",
                     (char *)"mem_access: \\valid_read(argv + argc)",15);
     /*@ assert Value: mem_access: \valid_read(argv + argc); */
@@ -85,12 +90,16 @@ int main(int argc, char **argv)
       int __gen_e_acsl_valid_read_2;
       int __gen_e_acsl_valid_4;
       __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(argv + argc),
-                                                      sizeof(char *));
+                                                      sizeof(char *),
+                                                      (void *)argv,
+                                                      (void *)(& argv));
       __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",(char *)"main",
                       (char *)"mem_access: \\valid_read(argv + argc)",16);
       /*@ assert Value: mem_access: \valid_read(argv + argc); */
       __gen_e_acsl_valid_4 = __e_acsl_valid((void *)*(argv + argc),
-                                            sizeof(char));
+                                            sizeof(char),
+                                            (void *)*(argv + argc),
+                                            (void *)(argv + argc));
       __gen_e_acsl_and = __gen_e_acsl_valid_4;
     }
     else __gen_e_acsl_and = 0;
@@ -113,12 +122,16 @@ int main(int argc, char **argv)
           int __gen_e_acsl_valid_read_3;
           int __gen_e_acsl_valid_5;
           __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)(argv + i),
-                                                          sizeof(char *));
+                                                          sizeof(char *),
+                                                          (void *)argv,
+                                                          (void *)(& argv));
           __e_acsl_assert(__gen_e_acsl_valid_read_3,(char *)"RTE",
                           (char *)"main",
                           (char *)"mem_access: \\valid_read(argv + i)",19);
           __gen_e_acsl_valid_5 = __e_acsl_valid((void *)*(argv + i),
-                                                sizeof(char));
+                                                sizeof(char),
+                                                (void *)*(argv + i),
+                                                (void *)(argv + i));
           __gen_e_acsl_and_2 = __gen_e_acsl_valid_5;
         }
         else __gen_e_acsl_and_2 = 0;
@@ -138,12 +151,16 @@ int main(int argc, char **argv)
             int __gen_e_acsl_valid_6;
             __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)(
                                                             argv + i),
-                                                            sizeof(char *));
+                                                            sizeof(char *),
+                                                            (void *)argv,
+                                                            (void *)(& argv));
             __e_acsl_assert(__gen_e_acsl_valid_read_4,(char *)"RTE",
                             (char *)"main",
                             (char *)"mem_access: \\valid_read(argv + i)",20);
             __gen_e_acsl_valid_6 = __e_acsl_valid((void *)(*(argv + i) + __gen_e_acsl_k_2),
-                                                  sizeof(char));
+                                                  sizeof(char),
+                                                  (void *)*(argv + i),
+                                                  (void *)(argv + i));
             if (__gen_e_acsl_valid_6) ;
             else {
               __gen_e_acsl_forall_2 = 0;
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_memalign.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_memalign.c
index ed712a0a82450f97fbb6f5f00547118629087ca2..807689112cbd77112c5a1bc3d175ec53a772a656 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_memalign.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_memalign.c
@@ -24,7 +24,8 @@ int main(int argc, char const **argv)
                                                     sizeof(char *));
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid;
-      __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(char));
+      __gen_e_acsl_valid = __e_acsl_valid((void *)p,sizeof(char),(void *)p,
+                                          (void *)(& p));
       __gen_e_acsl_and = __gen_e_acsl_valid;
     }
     else __gen_e_acsl_and = 0;
@@ -54,7 +55,8 @@ int main(int argc, char const **argv)
                                                       sizeof(char *));
     if (__gen_e_acsl_initialized_2) {
       int __gen_e_acsl_valid_2;
-      __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(char));
+      __gen_e_acsl_valid_2 = __e_acsl_valid((void *)p,sizeof(char),(void *)p,
+                                            (void *)(& p));
       __gen_e_acsl_and_2 = __gen_e_acsl_valid_2;
     }
     else __gen_e_acsl_and_2 = 0;
@@ -89,7 +91,8 @@ int main(int argc, char const **argv)
                                                       sizeof(char *));
     if (__gen_e_acsl_initialized_3) {
       int __gen_e_acsl_valid_3;
-      __gen_e_acsl_valid_3 = __e_acsl_valid((void *)a,sizeof(char));
+      __gen_e_acsl_valid_3 = __e_acsl_valid((void *)a,sizeof(char),(void *)a,
+                                            (void *)(& a));
       __gen_e_acsl_and_3 = __gen_e_acsl_valid_3;
     }
     else __gen_e_acsl_and_3 = 0;
@@ -119,7 +122,8 @@ int main(int argc, char const **argv)
                                                       sizeof(char *));
     if (__gen_e_acsl_initialized_4) {
       int __gen_e_acsl_valid_4;
-      __gen_e_acsl_valid_4 = __e_acsl_valid((void *)a,sizeof(char));
+      __gen_e_acsl_valid_4 = __e_acsl_valid((void *)a,sizeof(char),(void *)a,
+                                            (void *)(& a));
       __gen_e_acsl_and_4 = __gen_e_acsl_valid_4;
     }
     else __gen_e_acsl_and_4 = 0;
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_ptr.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_ptr.c
index 4e4c6777f405f23aa6f6af335f5b4c4ed0eee2e6..ecf41c7d55ec8f48443d951445a2cc4d0f5e1320 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_ptr.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_ptr.c
@@ -21,7 +21,8 @@ int main(void)
                                                     sizeof(int *));
     if (__gen_e_acsl_initialized) {
       int __gen_e_acsl_valid_read;
-      __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)p,sizeof(int));
+      __gen_e_acsl_valid_read = __e_acsl_valid_read((void *)p,sizeof(int),
+                                                    (void *)p,(void *)(& p));
       __gen_e_acsl_and = __gen_e_acsl_valid_read;
     }
     else __gen_e_acsl_and = 0;
@@ -64,7 +65,9 @@ int main(void)
       {
         int __gen_e_acsl_valid_read_2;
         __gen_e_acsl_valid_read_2 = __e_acsl_valid_read((void *)(& t[2] - i),
-                                                        sizeof(int));
+                                                        sizeof(int),
+                                                        (void *)(& t[2]),
+                                                        (void *)(& t[2]));
         __e_acsl_assert(__gen_e_acsl_valid_read_2,(char *)"RTE",
                         (char *)"main",
                         (char *)"mem_access: \\valid_read(&t[2] - i)",19);
@@ -86,7 +89,9 @@ int main(void)
                                                       sizeof(int *));
     if (__gen_e_acsl_initialized_2) {
       int __gen_e_acsl_valid_read_3;
-      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)p,sizeof(int));
+      __gen_e_acsl_valid_read_3 = __e_acsl_valid_read((void *)p,sizeof(int),
+                                                      (void *)p,
+                                                      (void *)(& p));
       __gen_e_acsl_and_2 = __gen_e_acsl_valid_read_3;
     }
     else __gen_e_acsl_and_2 = 0;
@@ -100,7 +105,8 @@ int main(void)
   {
     int __gen_e_acsl_valid_read_4;
     __gen_e_acsl_valid_read_4 = __e_acsl_valid_read((void *)(p + k),
-                                                    sizeof(int));
+                                                    sizeof(int),(void *)p,
+                                                    (void *)(& p));
     __e_acsl_assert(__gen_e_acsl_valid_read_4,(char *)"RTE",(char *)"main",
                     (char *)"mem_access: \\valid_read(p + k)",27);
     __e_acsl_assert(*(p + k) == 3,(char *)"Assertion",(char *)"main",
diff --git a/src/plugins/e-acsl/tests/runtime/oracle/gen_stdout.c b/src/plugins/e-acsl/tests/runtime/oracle/gen_stdout.c
index 98061b7b8c8272473ae5b24b21a41d38f7ce49bd..3d8afb1549cc2095e8526464479c915d7cb7febd 100644
--- a/src/plugins/e-acsl/tests/runtime/oracle/gen_stdout.c
+++ b/src/plugins/e-acsl/tests/runtime/oracle/gen_stdout.c
@@ -20,21 +20,24 @@ int main(void)
   /*@ assert \valid(__fc_stderr); */
   {
     int __gen_e_acsl_valid;
-    __gen_e_acsl_valid = __e_acsl_valid((void *)stderr,sizeof(FILE));
+    __gen_e_acsl_valid = __e_acsl_valid((void *)stderr,sizeof(FILE),
+                                        (void *)stderr,(void *)(& stderr));
     __e_acsl_assert(__gen_e_acsl_valid,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(__fc_stderr)",8);
   }
   /*@ assert \valid(__fc_stdin); */
   {
     int __gen_e_acsl_valid_2;
-    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)stdin,sizeof(FILE));
+    __gen_e_acsl_valid_2 = __e_acsl_valid((void *)stdin,sizeof(FILE),
+                                          (void *)stdin,(void *)(& stdin));
     __e_acsl_assert(__gen_e_acsl_valid_2,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(__fc_stdin)",9);
   }
   /*@ assert \valid(__fc_stdout); */
   {
     int __gen_e_acsl_valid_3;
-    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)stdout,sizeof(FILE));
+    __gen_e_acsl_valid_3 = __e_acsl_valid((void *)stdout,sizeof(FILE),
+                                          (void *)stdout,(void *)(& stdout));
     __e_acsl_assert(__gen_e_acsl_valid_3,(char *)"Assertion",(char *)"main",
                     (char *)"\\valid(__fc_stdout)",10);
   }
diff --git a/src/plugins/e-acsl/translate.ml b/src/plugins/e-acsl/translate.ml
index d56b16f3667f0037ce4911fe0e6e254dd6fb1cf4..1406bd12d44cac9d147f89a172df1856963cb980 100644
--- a/src/plugins/e-acsl/translate.ml
+++ b/src/plugins/e-acsl/translate.ml
@@ -35,7 +35,7 @@ let handle_error f env =
   Env.Context.restore env
 
 (* internal to [named_predicate_to_exp] but put it outside in order to not add
-   extra tedious parameter. 
+   extra tedious parameter.
    It is [true] iff we are currently visiting \valid. *)
 let is_visiting_valid = ref false
 
@@ -163,8 +163,8 @@ let constant_to_exp ~loc t = function
   | LStr s -> Cil.new_exp ~loc (Const (CStr s)), false
   | LWStr s -> Cil.new_exp ~loc (Const (CWStr s)), false
   | LChr c -> Cil.new_exp ~loc (Const (CChr c)), false
-  | LReal {r_literal=s; r_nearest=f; r_lower=l; r_upper=u} -> 
-    if l <> u then 
+  | LReal {r_literal=s; r_nearest=f; r_lower=l; r_upper=u} ->
+    if l <> u then
       Options.warning ~current:true ~once:true
 	"approximating a real number by a float";
     Cil.new_exp ~loc (Const (CReal (f, FLongDouble, Some s))), false
@@ -225,11 +225,11 @@ let cast_integer_to_float lty lty_t e =
     e
 
 let rec thost_to_host kf env = function
-  | TVar { lv_origin = Some v } -> 
+  | TVar { lv_origin = Some v } ->
     Var (Cil.get_varinfo (Env.get_behavior env) v), env, v.vname
-  | TVar ({ lv_origin = None } as logic_v) -> 
+  | TVar ({ lv_origin = None } as logic_v) ->
     Var (Env.Logic_binding.get env logic_v), env, logic_v.lv_name
-  | TResult _typ -> 
+  | TResult _typ ->
     let vis = Env.get_visitor env in
     let kf = Extlib.the vis#current_kf in
     let lhost = Misc.result_lhost kf in
@@ -242,16 +242,16 @@ let rec thost_to_host kf env = function
 
 and toffset_to_offset ?loc kf env = function
   | TNoOffset -> NoOffset, env
-  | TField(f, offset) -> 
+  | TField(f, offset) ->
     let offset, env = toffset_to_offset ?loc kf env offset in
     Field(f, offset), env
-  | TIndex(t, offset) -> 
+  | TIndex(t, offset) ->
     let e, env = term_to_exp kf env t in
     let offset, env = toffset_to_offset kf env offset in
     Index(e, offset), env
   | TModel _ -> not_yet env "model"
 
-and tlval_to_lval kf env (host, offset) = 
+and tlval_to_lval kf env (host, offset) =
   let host, env, name = thost_to_host kf env host in
   let offset, env = toffset_to_offset kf env offset in
   let name = match offset with NoOffset -> name | Field _ | Index _ -> "" in
@@ -260,13 +260,13 @@ and tlval_to_lval kf env (host, offset) =
 (* the returned boolean says that the expression is an mpz_string;
    the returned string is the name of the generated variable corresponding to
    the term. *)
-and context_insensitive_term_to_exp kf env t = 
+and context_insensitive_term_to_exp kf env t =
   let loc = t.term_loc in
   match t.term_node with
   | TConst c ->
     let c, is_mpz_string = constant_to_exp ~loc t c in
     c, env, is_mpz_string, ""
-  | TLval lv -> 
+  | TLval lv ->
     let lv, env, name = tlval_to_lval kf env lv in
     Cil.new_exp ~loc (Lval lv), env, false, name
   | TSizeOf ty -> Cil.sizeOf ~loc ty, env, false, "sizeof"
@@ -287,7 +287,7 @@ and context_insensitive_term_to_exp kf env t =
 	| BNot -> "__gmpz_com", "bnot"
 	| LNot -> assert false
       in
-      let _, e, env = 
+      let _, e, env =
 	Env.new_var_and_mpz_init
 	  ~loc
 	  env
@@ -322,8 +322,8 @@ and context_insensitive_term_to_exp kf env t =
       let name = name_of_mpz_arith_bop bop in
       let mk_stmts _ e = [ Misc.mk_call ~loc name [ e; e1; e2 ] ] in
       let name = name_of_binop bop in
-      let _, e, env = 
-	Env.new_var_and_mpz_init ~loc ~name env (Some t) mk_stmts 
+      let _, e, env =
+	Env.new_var_and_mpz_init ~loc ~name env (Some t) mk_stmts
       in
       e, env, false, ""
     else
@@ -354,16 +354,16 @@ and context_insensitive_term_to_exp kf env t =
         let name = name_of_binop bop ^ "_guard" in
         comparison_to_exp ~loc kf env Typing.gmp ~e1:e2 ~name Eq t2 zero t
       in
-      let mk_stmts _v e = 
+      let mk_stmts _v e =
 	assert (Gmpz.is_t ty);
 	let vis = Env.get_visitor env in
 	let kf = Extlib.the vis#current_kf in
-	let cond = 
-	  Misc.mk_e_acsl_guard 
-	    (Env.annotation_kind env) 
+	let cond =
+	  Misc.mk_e_acsl_guard
+	    (Env.annotation_kind env)
 	    kf
 	    guard
-	    (Logic_const.prel ~loc (Req, t2, zero)) 
+	    (Logic_const.prel ~loc (Req, t2, zero))
 	in
 	Env.add_assert env cond (Logic_const.prel (Rneq, t2, zero));
 	let instr = Misc.mk_call ~loc name [ e; e1; e2 ] in
@@ -424,10 +424,10 @@ and context_insensitive_term_to_exp kf env t =
     let e, env = add_cast ~loc ~name:"cast" env (Some ty) false (Some t) e in
     e, env, false, ""
   | TLogic_coerce _ -> assert false (* handle in [term_to_exp] *)
-  | TAddrOf lv -> 
+  | TAddrOf lv ->
     let lv, env, _ = tlval_to_lval kf env lv in
     Cil.mkAddrOf ~loc lv, env, false, "addrof"
-  | TStartOf lv -> 
+  | TStartOf lv ->
     let lv, env, _ = tlval_to_lval kf env lv in
     Cil.mkAddrOrStartOf ~loc lv, env, false, "startof"
   | Tapp(li, [], args) when Builtins.mem li.l_var_info.lv_name ->
@@ -468,7 +468,7 @@ and context_insensitive_term_to_exp kf env t =
     let res3 = term_to_exp kf (Env.push env2) t3 in
     let e, env = conditional_to_exp loc (Some t) e1 res2 res3 in
     e, env, false, ""
-  | Tat(t, LogicLabel(_, label)) when label = "Here" -> 
+  | Tat(t, LogicLabel(_, label)) when label = "Here" ->
     let e, env = term_to_exp kf env t in
     e, env, false, ""
   | Tat(t', label) ->
@@ -503,7 +503,7 @@ and context_insensitive_term_to_exp kf env t =
    constructs. *)
 and term_to_exp kf env t =
   let generate_rte = Env.generate_rte env in
-  Options.feedback ~dkey ~level:4 "translating term %a (rte? %b)" 
+  Options.feedback ~dkey ~level:4 "translating term %a (rte? %b)"
     Printer.pp_term t generate_rte;
   let env = Env.rte env false in
   let t = match t.term_node with TLogic_coerce(_, t) -> t | _ -> t in
@@ -550,18 +550,27 @@ and comparison_to_exp
 (* \base_addr, \block_length and \freeable annotations *)
 and mmodel_call ~loc kf name ctx env t =
   let e, env = term_to_exp kf (Env.rte env true) t in
-  let _, res, env = 
+  let _, res, env =
     Env.new_var
       ~loc
       ~name
       env
       None
-      ctx 
-      (fun v _ -> 
+      ctx
+      (fun v _ ->
 	[ Misc.mk_call ~loc ~result:(Cil.var v) (Misc.mk_api_name name) [ e ] ])
   in
   res, env, false, name
 
+and get_c_term_type = function
+  | Ctype ty -> ty
+  | _ -> assert false
+
+and mk_ptr_sizeof typ loc =
+  match Cil.unrollType typ with
+  | TPtr (t', _) -> Cil.new_exp ~loc (SizeOf t')
+  | _ -> assert false
+
 (* \valid, \offset and \initialized annotations *)
 and mmodel_call_with_size ~loc kf name ctx env t =
   let e, env = term_to_exp kf (Env.rte env true) t in
@@ -573,50 +582,68 @@ and mmodel_call_with_size ~loc kf name ctx env t =
       None
       ctx
       (fun v _ ->
-        let ty = match t.term_type with
-          | Ctype ty -> ty
-          | _ -> assert false
-        in
-        let sizeof = match Cil.unrollType ty with
-          | TPtr (t', _) -> Cil.new_exp ~loc (SizeOf t')
-          | _ -> assert false
-        in
-        [ Misc.mk_call
-            ~loc ~result:(Cil.var v) (Misc.mk_api_name name) [ e; sizeof ] ])
+        let ty = get_c_term_type t.term_type in
+        let sizeof = mk_ptr_sizeof ty loc in
+        let fname = Misc.mk_api_name name in
+        [ Misc.mk_call ~loc ~result:(Cil.var v) fname [ e; sizeof ] ])
+  in
+  res, env
+
+and mmodel_call_valid ~loc kf name ctx env t =
+  let e, env = term_to_exp kf (Env.rte env true) t in
+  let base, _ = Misc.ptr_index ~loc e in
+  let base_addr = match base.enode with
+    | AddrOf _ | Const _ -> base
+    | Lval(lv) | StartOf(lv) -> Cil.mkAddrOrStartOf ~loc lv
+    | _ -> assert false
+  in
+  let _, res, env =
+    Env.new_var
+      ~loc
+      ~name
+      env
+      None
+      ctx
+      (fun v _ ->
+        let ty = get_c_term_type t.term_type in
+        let sizeof = mk_ptr_sizeof ty loc in
+        let fname = Misc.mk_api_name name in
+        let args = [ e; sizeof; base; base_addr ] in
+        [ Misc.mk_call ~loc ~result:(Cil.var v) fname args ])
   in
   res, env
 
 and at_to_exp env t_opt label e =
   let stmt = E_acsl_label.get_stmt (Env.get_visitor env) label in
   (* generate a new variable denoting [\at(t',label)].
-     That is this variable which is the resulting expression. 
+     That is this variable which is the resulting expression.
      ACSL typing rule ensures that the type of this variable is the same as
      the one of [e]. *)
   let loc = Stmt.loc stmt in
   let res_v, res, new_env =
     Env.new_var
       ~loc
-      ~name:"at" 
+      ~name:"at"
       ~scope:Env.Function
       env
       t_opt
-      (Cil.typeOf e) 
+      (Cil.typeOf e)
       (fun _ _ -> [])
   in
   let env_ref = ref new_env in
   (* visitor modifying in place the labeled statement in order to store [e]
      in the resulting variable at this location (which is the only correct
      one). *)
-  let o = object 
+  let o = object
     inherit Visitor.frama_c_inplace
-    method !vstmt_aux stmt = 
+    method !vstmt_aux stmt =
       (* either a standard C affectation or an mpz one according to type of
-	 [e] *) 
+	 [e] *)
       let new_stmt = Gmpz.init_set ~loc (Cil.var res_v) res e in
       assert (!env_ref == new_env);
       (* generate the new block of code for the labeled statement and the
 	 corresponding environment *)
-      let block, new_env = 
+      let block, new_env =
 	Env.pop_and_get new_env new_stmt ~global_clear:false Env.Middle
       in
       let pre = match label with
@@ -654,7 +681,7 @@ and named_predicate_content_to_exp ?name kf env p =
     let env3 = Env.push env2 in
     let name = match name with None -> "and" | Some n -> n in
     conditional_to_exp ~name loc None e1 res2 (Cil.zero loc, env3)
-  | Por(p1, p2) -> 
+  | Por(p1, p2) ->
     (* p1 || p2 <==> if p1 then true else p2 *)
     let e1, env1 = named_predicate_to_exp kf (Env.rte env true) p1 in
     let env' = Env.push env1 in
@@ -662,21 +689,21 @@ and named_predicate_content_to_exp ?name kf env p =
     let name = match name with None -> "or" | Some n -> n in
     conditional_to_exp ~name loc None e1 (Cil.one loc, env') res2
   | Pxor _ -> not_yet env "xor"
-  | Pimplies(p1, p2) -> 
+  | Pimplies(p1, p2) ->
     (* (p1 ==> p2) <==> !p1 || p2 *)
-    named_predicate_to_exp 
+    named_predicate_to_exp
       ~name:"implies"
       kf
       env
       (Logic_const.por ~loc ((Logic_const.pnot ~loc p1), p2))
-  | Piff(p1, p2) -> 
+  | Piff(p1, p2) ->
     (* (p1 <==> p2) <==> (p1 ==> p2 && p2 ==> p1) *)
-    named_predicate_to_exp 
+    named_predicate_to_exp
       ~name:"equiv"
       kf
       env
       (Logic_const.pand ~loc
-	 (Logic_const.pimplies ~loc (p1, p2), 
+	 (Logic_const.pimplies ~loc (p1, p2),
 	  Logic_const.pimplies ~loc (p2, p1)))
   | Pnot p ->
     let e, env = named_predicate_to_exp kf env p in
@@ -688,9 +715,9 @@ and named_predicate_content_to_exp ?name kf env p =
     conditional_to_exp loc None e1 res2 res3
   | Plet _ -> not_yet env "let _ = _ in _"
   | Pforall _ | Pexists _ -> Quantif.quantif_to_exp kf env p
-  | Pat(p, LogicLabel(_, label)) when label = "Here" -> 
+  | Pat(p, LogicLabel(_, label)) when label = "Here" ->
     named_predicate_to_exp kf env p
-  | Pat(p', label) -> 
+  | Pat(p', label) ->
     (* convert [t'] to [e] in a separated local env *)
     let e, env = named_predicate_to_exp kf (Env.push env) p' in
     let e, env, is_string = at_to_exp env None label e in
@@ -698,13 +725,13 @@ and named_predicate_content_to_exp ?name kf env p =
     e, env
   | Pvalid_read(LogicLabel(_, label) as llabel, t) as pc
   | (Pvalid(LogicLabel(_, label) as llabel, t) as pc) when label = "Here" ->
-    let call_valid t = 
+    let call_valid t =
       let name = match pc with
 	| Pvalid _ -> "valid"
 	| Pvalid_read _ -> "valid_read"
 	| _ -> assert false
       in
-      mmodel_call_with_size ~loc kf name Cil.intType env t 
+      mmodel_call_valid ~loc kf name Cil.intType env t
     in
     if !is_visiting_valid then begin
       (* we already transformed \valid(t) into \initialized(&t) && \valid(t):
@@ -729,7 +756,7 @@ and named_predicate_content_to_exp ?name kf env p =
     (match t.term_node with
     (* optimisation when we know that the initialisation is ok *)
     | TAddrOf (TResult _, TNoOffset) -> Cil.one ~loc, env
-    | TAddrOf (TVar { lv_origin = Some vi }, TNoOffset) 
+    | TAddrOf (TVar { lv_origin = Some vi }, TNoOffset)
 	when vi.vformal || vi.vglob || Misc.is_generated_varinfo vi ->
       Cil.one ~loc, env
     | _ -> mmodel_call_with_size ~loc kf "initialized" Cil.intType env t)
@@ -757,7 +784,7 @@ and named_predicate_to_exp ?name kf ?rte env p =
     None
     e
 
-and translate_rte_annots: 
+and translate_rte_annots:
     'a. (Format.formatter -> 'a -> unit) -> 'a ->
   kernel_function -> Env.t -> code_annotation list -> Env.t =
   fun pp elt kf env l ->
@@ -767,9 +794,9 @@ and translate_rte_annots:
     let env =
       List.fold_left
         (fun env a -> match a.annot_content with
-        | AAssert(_, p) -> 
+        | AAssert(_, p) ->
 	  handle_error
-	    (fun env -> 
+	    (fun env ->
 	      Options.feedback ~dkey ~level:4 "prevent RTE from %a" pp elt;
 	      translate_named_predicate kf (Env.rte env false) p)
 	    env
@@ -786,20 +813,20 @@ and translate_rte kf env e =
   translate_rte_annots Printer.pp_exp e kf env l
 
 and translate_named_predicate kf env p =
-  Options.feedback ~dkey ~level:3 "translating predicate %a" 
+  Options.feedback ~dkey ~level:3 "translating predicate %a"
     Printer.pp_predicate p;
   let rte = Env.generate_rte env in
   Typing.type_named_predicate ~must_clear:rte p;
   let e, env = named_predicate_to_exp kf ~rte env p in
   assert (Typ.equal (Cil.typeOf e) Cil.intType);
   Env.add_stmt
-    env 
+    env
     (Misc.mk_e_acsl_guard ~reverse:true (Env.annotation_kind env) kf e p)
 
-let named_predicate_to_exp ?name kf env p = 
+let named_predicate_to_exp ?name kf env p =
   named_predicate_to_exp ?name kf env p (* forget optional argument ?rte *)
 
-let () = 
+let () =
   Quantif.term_to_exp_ref := term_to_exp;
   Quantif.predicate_to_exp_ref := named_predicate_to_exp
 
@@ -853,11 +880,11 @@ let assumes_predicate bhv =
 let original_project_ref = ref Project_skeleton.dummy
 let set_original_project p = original_project_ref := p
 
-let must_translate ppt = 
+let must_translate ppt =
   let selection =
     State_selection.of_list [ Property_status.self; Options.Valid.self ]
   in
-  Project.on ~selection 
+  Project.on ~selection
     !original_project_ref
     (fun ppt ->
       match Property_status.get ppt with
@@ -867,14 +894,14 @@ let must_translate ppt =
 
 let translate_preconditions kf kinstr env behaviors =
   let env = Env.set_annotation_kind env Misc.Precondition in
-  let do_behavior env b = 
+  let do_behavior env b =
     let assumes_pred = assumes_predicate b in
     List.fold_left
       (fun env p ->
          let do_it env =
            if must_translate (Property.ip_of_requires kf kinstr b p) then
              let loc = p.ip_content.pred_loc in
-             let p = 
+             let p =
                Logic_const.pimplies
                  ~loc
                  (assumes_pred,
@@ -887,13 +914,13 @@ let translate_preconditions kf kinstr env behaviors =
 	handle_error do_it env)
       env
       b.b_requires
-  in 
+  in
   List.fold_left do_behavior env behaviors
 
 let translate_postconditions kf kinstr env behaviors =
   let env = Env.set_annotation_kind env Misc.Postcondition in
       (* generate one guard by postcondition of each behavior *)
-  let do_behavior env b = 
+  let do_behavior env b =
     let assumes_pred = assumes_predicate b in
     List.fold_left
       (fun env (t, p as post) ->
@@ -901,23 +928,23 @@ let translate_postconditions kf kinstr env behaviors =
 	  let env =
 	    handle_error
 	      (fun env ->
-		if b.b_assigns <> WritesAny then 
+		if b.b_assigns <> WritesAny then
 		  not_yet env "assigns clause in behavior";
-		if b.b_extended <> [] then 
+		if b.b_extended <> [] then
 		  not_yet env "grammar extensions in behavior";
 		env)
 	      env
 	  in
 	  let do_it env =
 	    match t with
-	    | Normal -> 
+	    | Normal ->
 	      let loc = p.ip_content.pred_loc in
 	      let p = p.ip_content in
-	      let p = 
-		Logic_const.pimplies 
+	      let p =
+		Logic_const.pimplies
 		  ~loc
-		  (Logic_const.pold ~loc assumes_pred, 
-		   Logic_const.unamed ~loc p.pred_content) 
+		  (Logic_const.pold ~loc assumes_pred,
+		   Logic_const.unamed ~loc p.pred_content)
 	      in
 	      translate_named_predicate kf env p
 	    | Exits | Breaks | Continues | Returns ->
@@ -927,7 +954,7 @@ let translate_postconditions kf kinstr env behaviors =
 	else env)
       env
       b.b_post_cond
-  in 
+  in
   List.fold_left do_behavior env behaviors
 
 let translate_pre_spec kf kinstr env spec =
@@ -967,32 +994,32 @@ let translate_pre_spec kf kinstr env spec =
   in
   let env = convert_unsupported_clauses env in
   handle_error
-    (fun env -> translate_preconditions kf kinstr env spec.spec_behavior) 
+    (fun env -> translate_preconditions kf kinstr env spec.spec_behavior)
     env
 
-let translate_post_spec kf kinstr env spec = 
+let translate_post_spec kf kinstr env spec =
   handle_error
-    (fun env -> translate_postconditions kf kinstr env spec.spec_behavior) 
+    (fun env -> translate_postconditions kf kinstr env spec.spec_behavior)
     env
 
 let translate_pre_code_annotation kf stmt env annot =
   let convert env = match annot.annot_content with
-    | AAssert(l, p) -> 
+    | AAssert(l, p) ->
       if must_translate (Property.ip_of_code_annot_single kf stmt annot) then
 	let env = Env.set_annotation_kind env Misc.Assertion in
-	if l <> [] then 
+	if l <> [] then
 	  not_yet env "@[assertion applied only on some behaviors@]";
 	translate_named_predicate kf env p
       else
 	env
     | AStmtSpec(l, spec) ->
-      if l <> [] then 
+      if l <> [] then
         not_yet env "@[statement contract applied only on some behaviors@]";
       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 Misc.Invariant in
-	if l <> [] then 
+	if l <> [] then
 	  not_yet env "@[invariant applied only on some behaviors@]";
 	let env = translate_named_predicate kf env p in
 	if loop_invariant then Env.add_loop_invariant env p else env
@@ -1018,8 +1045,8 @@ let translate_pre_code_annotation kf stmt env annot =
 let translate_post_code_annotation kf stmt env annot =
   let convert env = match annot.annot_content with
     | AStmtSpec(_, spec) -> translate_post_spec kf (Kstmt stmt) env spec
-    | AAssert _ 
-    | AInvariant _ 
+    | AAssert _
+    | AInvariant _
     | AVariant _
     | AAssigns _
     | AAllocation _
diff --git a/src/plugins/e-acsl/visit.ml b/src/plugins/e-acsl/visit.ml
index 314aa0702468475744cb6a23d7cb1a581d902394..a159cdea254416f7429a1357bf7b2fcfd9261655 100644
--- a/src/plugins/e-acsl/visit.ml
+++ b/src/plugins/e-acsl/visit.ml
@@ -114,8 +114,8 @@ class e_acsl_visitor prj generate = object (self)
   val global_vars: init option Varinfo.Hashtbl.t = Varinfo.Hashtbl.create 7
   (* Hashtable mapping global variables (as Cil_type.varinfo) to their
      initializers aiming to capture memory allocated by global variable
-     declarations and initilisation. At runtime the memory blocks corresponding
-     to space occupied by global are recorded via a call to
+     declarations and initialization. At runtime the memory blocks
+     corresponding to space occupied by global are recorded via a call to
      [__gen_e_acsl_globals_init] instrumented at the beginning of the
      [main] function. Each variable stored by [global_vars] will be handled in
      the body of [__gen_e_acsl_globals_init] as follows:
@@ -143,7 +143,7 @@ class e_acsl_visitor prj generate = object (self)
     if generate then Project.copy ~selection ~src:cur prj;
     Cil.DoChildrenPost
       (fun f ->
-        (* extend the main with forward initialization and put it at end *)
+        (* extend [main] with forward initialization and put it at end *)
         if generate then begin
           let must_init =
             not (Literal_strings.is_empty ())
@@ -204,7 +204,7 @@ class e_acsl_visitor prj generate = object (self)
                     Cil.mkStmtOneInstr ~valid_sid:true (Set(Cil.var vi, e, loc))
                     :: Misc.mk_store_stmt ~str_size vi
                     :: Misc.mk_full_init_stmt ~addr:false vi
-                    :: Misc.mk_readonly vi
+                    :: Misc.mk_mark_readonly vi
                     :: stmts)
                   stmts
               in
@@ -291,10 +291,10 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]"
             in
             Project.on prj build_initializer ()
           end; (* must_init *)
-          (* Add a call to "__e_acsl_memory_init" that initializes memory
+          (* Add a call to [__e_acsl_memory_init] that initializes memory
              storage and potentially records program arguments. Parameters to
-             the "__e_acsl_memory_init" are addresses of program arguments or
-             NULLs if main is declared without arguments. *)
+             [__e_acsl_memory_init] are addresses of program arguments or
+             NULLs if [main] is declared without arguments. *)
           let build_mmodel_initializer () =
             let loc = Location.unknown in
             let nulls = [ Cil.zero loc ; Cil.zero loc ] in
@@ -354,7 +354,7 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]"
   | g ->
     let do_it = function
       | GVar(vi, _, _) ->
-        vi.vghost <- false; ()
+        vi.vghost <- false
       | GFun({ svar = vi } as fundec, _) ->
         vi.vghost <- false;
         Builtins.update vi.vname vi;
@@ -380,7 +380,7 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]"
     if generate then Cil.DoChildrenPost(fun g -> List.iter do_it g; g)
     else Cil.DoChildren
 
-  (* Add mappings from global variables to their initializers to [global_vars].
+  (* Add mappings from global variables to their initializers in [global_vars].
      Note that the below function captures only [SingleInit]s. All compound
      initializers (which contain single ones) are unrapped and thrown away. *)
   method !vinit vi _off _i =
@@ -390,7 +390,7 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]"
         Cil.DoChildrenPost
           (fun i ->
             (match is_initializer with
-            (* Note the use of [add] instead [replace]. This is because a
+            (* Note the use of [add] instead of [replace]. This is because a
              single variable can be associated with multiple initializers
              and all of them need to be captured. *)
             | true -> Varinfo.Hashtbl.add global_vars vi (Some i)
@@ -710,11 +710,7 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]"
       | Var vi, NoOffset -> vi.vglob || vi.vformal
       | _ -> false
     in
-(*    Options.feedback "%a? %a (%b && %b)"
-      Printer.pp_lval assigned_lv
-      Printer.pp_lval checked_lv
-      (not (may_safely_ignore assigned_lv))
-      (Pre_analysis.must_model_lval ~kf ~stmt checked_lv);*)
+
     if not (may_safely_ignore assigned_lv) &&
       Mmodel_analysis.must_model_lval ~kf ~stmt checked_lv
     then
@@ -722,8 +718,8 @@ you must call function `%s' and `__e_acsl_memory_clean by yourself.@]"
         (* must be in the new project to build a new stmt *)
         Project.on
           prj
-          Misc.mk_debug_mmodel_stmt
-          (Misc.mk_initialize loc assigned_lv)
+          (Misc.mk_initialize ~loc)
+          assigned_lv
       in
       let before = Cil.memo_stmt self#behavior stmt in
       let new_stmt = Cil.memo_stmt self#behavior new_stmt in