diff --git a/src/kernel_services/abstract_interp/abstract_offset.ml b/src/kernel_services/abstract_interp/abstract_offset.ml
index 2184c2c297c5f0fa2c902b61fd3220fb1215a5c5..5a573091cbc7881db853f9c68bba15a9384908cb 100644
--- a/src/kernel_services/abstract_interp/abstract_offset.ml
+++ b/src/kernel_services/abstract_interp/abstract_offset.ml
@@ -56,7 +56,7 @@ sig
   val append : t -> t -> t (* Does not check that the appened offset fits *)
   val join : t -> t -> t
   val of_cil_offset : (Cil_types.exp -> Ival.t) -> Cil_types.typ -> Cil_types.offset -> t
-  val of_ival : Cil_types.typ -> Cil_types.typ -> Ival.t -> t
+  val of_ival : base_typ:Cil_types.typ -> typ:Cil_types.typ -> Ival.t -> t
   val of_term_offset : Cil_types.typ -> Cil_types.term_offset -> t
   val is_singleton : t -> bool
 end
@@ -97,7 +97,8 @@ struct
     match array_size with
     | None -> None, None
     | Some size_exp ->
-      Some Integer.zero, Cil.constFoldToInt size_exp
+      Some Integer.zero,
+      Option.map Integer.pred (Cil.constFoldToInt size_exp)
 
   let array_range array_size =
     let l,u = array_bounds array_size in
@@ -119,34 +120,34 @@ struct
         Index (idx, elem_typ, of_cil_offset oracle elem_typ sub)
       | _ -> assert false
 
-  let rec of_ival base_typ typ ival =
+  let rec of_ival ~base_typ ~typ ival =
     if Ival.is_zero ival && type_compatible base_typ typ then
       NoOffset typ
     else
       match Cil.unrollType base_typ with
       | TArray (elem_typ, array_size, _, _) ->
-        begin try
+        let range, rem =
+          try
             let elem_size = Integer.of_int (Cil.bitsSizeOf elem_typ) in
             if Integer.is_zero elem_size then (* array of elements of size 0 *)
               if Ival.is_zero ival then (* the whole range is valid *)
-                let sub = of_ival elem_typ typ ival in
-                Index (array_range array_size, elem_typ, sub)
+                array_range array_size, ival
               else (* Non-zero offset cannot represent anything here *)
                 raise Abstract_interp.Error_Top
             else
-              let range = Ival.scale_div ~pos:true elem_size ival
-              and range_rem = Ival.scale_rem ~pos:true elem_size ival in
-              let sub = of_ival elem_typ typ range_rem in
-              Index (range, elem_typ, sub)
+              Ival.scale_div ~pos:true elem_size ival,
+              Ival.scale_rem ~pos:true elem_size ival
           with Cil.SizeOfError (_,_) ->
             (* Cil.bitsSizeOf can raise an exception when elements are
                themselves array of execution-time size *)
             if Ival.is_zero ival then
-              let sub = of_ival elem_typ typ ival in
-              Index (ival, elem_typ, sub)
+              ival, ival
             else
               raise Abstract_interp.Error_Top
-        end
+          in
+          assert_valid_index range array_size;
+          let sub = of_ival ~base_typ:elem_typ ~typ rem in
+          Index (range, elem_typ, sub)
 
       | TComp (ci, _, _) ->
         if not ci.cstruct then
@@ -158,11 +159,11 @@ struct
             | fi :: q ->
               let offset, width = Cil.fieldBitsOffset fi in
               let l = Integer.(of_int offset) in
-              let u = Integer.(add l (of_int width)) in
+              let u = Integer.(pred (add l (of_int width))) in
               let range = Ival.inject_range (Some l) (Some u) in
               if Ival.is_included ival range then
                 let sub_ival = Ival.add_singleton_int (Integer.neg l) ival in
-                Field (fi, of_ival fi.ftype typ sub_ival)
+                Field (fi, of_ival ~base_typ:fi.ftype ~typ sub_ival)
               else
                 find_field q
           in
@@ -170,14 +171,14 @@ struct
 
       | _ -> raise Abstract_interp.Error_Top
 
-  let of_ival base_typ typ ival =
+  let of_ival ~base_typ ~typ ival =
     if Ival.is_small_set ival then
       let f i acc =
-        Bottom.join join acc (`Value (of_ival base_typ typ i))
+        Bottom.join join acc (`Value (of_ival ~base_typ ~typ i))
       in
       Bottom.non_bottom (Ival.fold_enum f ival `Bottom)
     else
-      of_ival base_typ typ ival
+      of_ival ~base_typ ~typ ival
 
   let index_of_term array_size t = (* Exact constant ranges *)
     match t.Cil_types.term_node with
@@ -239,8 +240,8 @@ struct
     try `Value (TypedOffset.of_cil_offset oracle base_typ offset)
     with Abstract_interp.Error_Top -> `Top
 
-  let of_ival base_typ typ ival =
-    try `Value (TypedOffset.of_ival base_typ typ ival)
+  let of_ival ~base_typ ~typ ival =
+    try `Value (TypedOffset.of_ival ~base_typ ~typ ival)
     with Abstract_interp.Error_Top -> `Top
 
   let of_term_offset base_typ toffset =
diff --git a/src/kernel_services/abstract_interp/abstract_offset.mli b/src/kernel_services/abstract_interp/abstract_offset.mli
index 8d0dde615cec5b1beb78ef27c2da599102ea8d72..519427ffd2aec3ea53284ab8860d2b61c69b559e 100644
--- a/src/kernel_services/abstract_interp/abstract_offset.mli
+++ b/src/kernel_services/abstract_interp/abstract_offset.mli
@@ -28,7 +28,7 @@ sig
   val append : t -> t -> t (* Does not check that the appened offset fits *)
   val join : t -> t -> t
   val of_cil_offset : (Cil_types.exp -> Ival.t) -> Cil_types.typ -> Cil_types.offset -> t
-  val of_ival : Cil_types.typ -> Cil_types.typ -> Ival.t -> t
+  val of_ival : base_typ:Cil_types.typ -> typ:Cil_types.typ -> Ival.t -> t
   val of_term_offset : Cil_types.typ -> Cil_types.term_offset -> t
   val is_singleton : t -> bool
 end
diff --git a/src/kernel_services/abstract_interp/memory_map.ml b/src/kernel_services/abstract_interp/memory_map.ml
index 0beaf5ac7708f292dd93bcf0f2c0bdf4f8c7f331..ae56952e492c1ed7bb5fa4cd932b71b7a1da7854 100644
--- a/src/kernel_services/abstract_interp/memory_map.ml
+++ b/src/kernel_services/abstract_interp/memory_map.ml
@@ -127,7 +127,7 @@ struct
   type location = Abstract_offset.typed_offset
   type value = Value.t
 
-  type 'fieldmap memory' =
+  type 'fieldmap memory =
     | Raw of bit
     | Scalar of memory_scalar
     | Struct of 'fieldmap memory_struct
@@ -140,16 +140,16 @@ struct
   and 'fieldmap memory_struct = {
     struct_value: 'fieldmap;
     struct_info: Cil_types.compinfo;
-    struct_padding: bit; (* for missing fields *)
+    struct_padding: bit; (* for missing fields and padding *)
   }
   (* unions are handled separately from struct to avoid confusion and error *)
   and 'fieldmap memory_union = {
-    union_value: 'fieldmap memory';
+    union_value: 'fieldmap memory;
     union_field: Cil_types.fieldinfo;
     union_padding: bit;
   }
   and 'fieldmap memory_array = {
-    array_value: 'fieldmap memory';
+    array_value: 'fieldmap memory;
     array_cell_type: Cil_types.typ;
   }
 
@@ -166,7 +166,7 @@ struct
   end
 
   module rec Memory :
-    Hptmap.V with type t = FieldMap.t memory' =
+    Hptmap.V with type t = FieldMap.t memory =
   struct
     include Datatype.Make (
       struct
@@ -183,14 +183,14 @@ struct
      to FieldMap and no constants, only functions *)
   and MemorySafe :
   sig
-    type t = FieldMap.t memory'
+    type t = FieldMap.t memory
     val pretty : Format.formatter -> t -> unit
     val hash : t -> int
     val equal : t -> t -> bool
     val compare : t -> t -> int
   end =
   struct
-    type t = FieldMap.t memory'
+    type t = FieldMap.t memory
 
     let rec pretty fmt =
       let rec leading_indexes acc = function
diff --git a/src/plugins/value/domains/multidim_domain.ml b/src/plugins/value/domains/multidim_domain.ml
index 055b2b278f7dc86b2622b2647a5b7d878a41f3ce..170c56321a7cf547d6252d41e7669f1292df7f2b 100644
--- a/src/plugins/value/domains/multidim_domain.ml
+++ b/src/plugins/value/domains/multidim_domain.ml
@@ -227,7 +227,7 @@ end
 module DomainPrototype =
 struct
   (* The domain is essentially a map from bases to individual memory abstractions *)
-  module Initial_Values = struct let v = [] end
+  module Initial_Values = struct let v = [[]] end
   module Deps = struct let l = [Ast.self] end
 
   include Hptmap.Make
@@ -269,7 +269,7 @@ struct
     let decide _ v1 v2 =
       Memory.narrow v1 v2
     in
-    let narrow = join ~cache ~symmetric:true ~idempotent:true ~decide in
+    let narrow = join ~cache ~symmetric:false ~idempotent:true ~decide in
     fun a b -> `Value (narrow a b)
 
   let join =
diff --git a/src/plugins/value/value_parameters.ml b/src/plugins/value/value_parameters.ml
index b6cf1f8372e87e9f32484e878209d371c6600147..df4f7885cbb5e9847bf47054b41569dbf8d85ebb 100644
--- a/src/plugins/value/value_parameters.ml
+++ b/src/plugins/value/value_parameters.ml
@@ -138,7 +138,6 @@ module Domains =
       let arg_name = "d1,...,dn"
       let help = "Enable a list of analysis domains."
       let default = Datatype.String.Set.of_list ["cvalue"]
-      (* let default = Datatype.String.Set.singleton "cvalue" *)
     end)
 let () = add_precision_dep Domains.parameter