diff --git a/src/plugins/value/domains/cvalue/builtins_malloc.ml b/src/plugins/value/domains/cvalue/builtins_malloc.ml
index 727ef69ca5040a887949e0e02cbe633d4238e380..dee1382281c94136b19e06645315db71d93de60e 100644
--- a/src/plugins/value/domains/cvalue/builtins_malloc.ml
+++ b/src/plugins/value/domains/cvalue/builtins_malloc.ml
@@ -30,6 +30,9 @@ let dkey = Value_parameters.register_category "malloc"
 let wkey_weak_alloc = Value_parameters.register_warn_category "malloc:weak"
 let () = Value_parameters.set_warn_status wkey_weak_alloc Log.Winactive
 
+let wkey_imprecise_alloc = Value_parameters.register_warn_category
+    "malloc:imprecise"
+
 (** {1 Dynamically allocated bases} *)
 
 module Base_hptmap = Hptmap.Make
@@ -363,12 +366,99 @@ let () =
     (alloc_fresh Weak Base.Malloc)
     ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf]))
 
+module Base_with_Size = Datatype.Pair (Base.Base) (Datatype.Integer)
+
+(* Extremely aggressive and imprecise allocation: a single weak base for each
+   region. *)
+module MallocedSingleMalloc =
+  State_builder.Option_ref (Base_with_Size)
+    (struct
+      let name = "Value.Builtins_malloc.MallocedSingleMalloc"
+      let dependencies = [Ast.self]
+    end)
+let () = Ast.add_monotonic_state MallocedSingleMalloc.self
+
+module MallocedSingleVLA =
+  State_builder.Option_ref (Base_with_Size)
+    (struct
+      let name = "Value.Builtins_malloc.MallocedSingleVLA"
+      let dependencies = [Ast.self]
+    end)
+let () = Ast.add_monotonic_state MallocedSingleVLA.self
+
+module MallocedSingleAlloca =
+  State_builder.Option_ref (Base_with_Size)
+    (struct
+      let name = "Value.Builtins_malloc.MallocedSingleAlloca"
+      let dependencies = [Ast.self]
+    end)
+let () = Ast.add_monotonic_state MallocedSingleAlloca.self
+
+let string_of_region = function
+  | Base.Malloc -> "via malloc/calloc/realloc"
+  | Base.VLA -> "related to variable-length arrays"
+  | Base.Alloca -> "via alloca"
+
+(* Only called when the 'weakest base' needs to be allocated. *)
+let alloc_imprecise_weakest_alloc region =
+  let stack = [ fst (Globals.entry_point ()), Kglobal ] in
+  let type_base =
+    TArray (Cil.charType, None, Cil.empty_size_cache (), [])
+  in
+  let var = create_new_var stack "alloc" type_base Weak in
+  Value_parameters.warning ~wkey:wkey_imprecise_alloc ~current:true ~once:true
+    "allocating a single weak variable for ALL dynamic allocations %s: %a"
+    (string_of_region region) Printer.pp_varinfo var;
+  let min_alloc = Int.minus_one in
+  let max_alloc = Bit_utils.max_bit_address () in
+  let variable_v =
+    Base.create_variable_validity ~weak:true ~min_alloc ~max_alloc
+  in
+  let new_base = Base.register_allocated_var var region (Base.Variable variable_v) in
+  register_malloced_base ~stack new_base;
+  new_base, max_alloc
+
+(* used by calloc_abstract *)
+let alloc_imprecise_weakest_abstract region =
+  let memo =
+    match region with
+    | Base.Malloc -> MallocedSingleMalloc.memo
+    | Base.VLA -> MallocedSingleVLA.memo
+    | Base.Alloca -> MallocedSingleAlloca.memo
+  in
+  memo (fun () -> alloc_imprecise_weakest_alloc region)
+
+let alloc_imprecise_weakest_aux region _stack _prefix _sizev state =
+  let new_base, max_alloc = alloc_imprecise_weakest_abstract region in
+  let new_state = add_uninitialized state new_base max_alloc in
+  let ret = V.inject new_base Ival.zero in
+  ret, new_state
+
+let alloc_imprecise_weakest ?returns_null region state actuals =
+  match actuals with
+  | [_, _size, _] ->
+    begin
+      let ret, new_state = alloc_imprecise_weakest_aux region [] "" _size state in
+      let c_values = wrap_fallible_alloc ?returns_null ret state new_state in
+      { Value_types.c_values = c_values ;
+        c_clobbered = Base.SetLattice.bottom;
+        c_cacheable = Value_types.NoCacheCallers;
+        c_from = None;
+      }
+    end
+  | _ -> raise (Builtins.Invalid_nb_of_args 1)
+
+let () = Builtins.register_builtin
+    "Frama_C_malloc_imprecise" (alloc_imprecise_weakest Base.Malloc)
+    ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf]))
+
+let zero_to_max_bytes () = Ival.inject_range
+    (Some Integer.zero) (Some (Bit_utils.max_byte_size ()))
+
 let alloc_size_ok intended_size =
   try
     let size = Cvalue.V.project_ival intended_size in
-    let ok_size =
-      Ival.inject_range (Some Integer.zero) (Some (Bit_utils.max_byte_size ()))
-    in
+    let ok_size = zero_to_max_bytes () in
     if Ival.is_included size ok_size then Alarmset.True
     else if Ival.intersects size ok_size then Alarmset.Unknown
     else Alarmset.False
@@ -422,7 +512,7 @@ let () =
 (* Variables that have been returned by a call to an allocation function
    at this callstack. The first allocated variable is at the top of the
    stack. Currently, the callstacks are truncated according to
-   [-val-malloc-functions]. *)
+   [-eva-alloc-functions]. *)
 module MallocedByStack = (* varinfo list Callstack.hashtbl *)
   State_builder.Hashtbl(Value_types.Callstack.Hashtbl)
     (Datatype.List(Base))
@@ -510,10 +600,18 @@ let () = Builtins.register_builtin
     ~replace:"__fc_vla_alloc" "Frama_C_vla_alloc_by_stack"
     (alloc_by_stack Base.VLA ~returns_null:false)
     ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf]))
+let () = Builtins.register_builtin
+    "Frama_C_vla_alloc_imprecise"
+    (alloc_imprecise_weakest Base.VLA ~returns_null:false)
+    ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf]))
 let () = Builtins.register_builtin
     ~replace:"alloca" "Frama_C_alloca"
     (alloc_by_stack ~prefix:"alloca" Base.Alloca ~returns_null:false)
     ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf]))
+let () = Builtins.register_builtin
+    "Frama_C_alloca_imprecise"
+    (alloc_imprecise_weakest Base.Alloca ~returns_null:false)
+    ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf]))
 
 (* Equivalent to [alloc_by_stack], but for [calloc]. *)
 let calloc_by_stack : Db.Value.builtin = fun state actuals ->
@@ -524,6 +622,18 @@ let () = Builtins.register_builtin
     ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf;
                                        Cil.theMachine.Cil.typeOfSizeOf]))
 
+(* Equivalent to [malloc_imprecise_weakest], but for [calloc]. *)
+let calloc_imprecise_weakest : Db.Value.builtin = fun state actuals ->
+  let calloc_f _stack _prefix _sizev _state =
+    alloc_imprecise_weakest_abstract Base.Malloc
+  in
+  calloc_abstract calloc_f state actuals
+
+let () = Builtins.register_builtin
+    "Frama_C_calloc_imprecise" calloc_imprecise_weakest
+    ~typ:(fun () -> (Cil.voidPtrType, [Cil.theMachine.Cil.typeOfSizeOf;
+                                       Cil.theMachine.Cil.typeOfSizeOf]))
+
 (** {1 Free} *)
 
 (* Change all references to bases into ESCAPINGADDR into the given state,
@@ -819,6 +929,33 @@ let () = Builtins.register_builtin
     ~typ:(fun () -> (Cil.voidPtrType, [Cil.voidPtrType;
                                        Cil.theMachine.Cil.typeOfSizeOf]))
 
+let realloc_imprecise_weakest state args = match args with
+  | [ (_,ptr,_); (_,_size,_) ] ->
+    let (bases, card_ok, _null) = resolve_bases_to_free ptr in
+    if card_ok > 0 then
+      let orig_state = state in
+      let ret, state = alloc_imprecise_weakest_aux Base.Malloc [] "" _size state in
+      (* free old bases. *)
+      let state, changed = free_aux state ~strong:false bases in
+      let c_values = wrap_fallible_alloc ret orig_state state in
+      { Value_types.c_values;
+        c_clobbered = Builtins.clobbered_set_from_ret state ret;
+        c_cacheable = Value_types.NoCacheCallers;
+        c_from = Some changed;
+      }
+    else (* Invalid call. *)
+      { Value_types.c_values = [] ;
+        c_clobbered = Base.SetLattice.bottom;
+        c_cacheable = Value_types.NoCacheCallers;
+        c_from = None;
+      }
+  | _ -> raise (Builtins.Invalid_nb_of_args 2)
+
+let () = Builtins.register_builtin
+    "Frama_C_realloc_imprecise" realloc_imprecise_weakest
+    ~typ:(fun () -> (Cil.voidPtrType, [Cil.voidPtrType;
+                                       Cil.theMachine.Cil.typeOfSizeOf]))
+
 (** {1 Leak detection} *)
 
 (* Experimental, not to be released, leak detection built-in. *)
diff --git a/tests/builtins/calloc.c b/tests/builtins/calloc.c
index 648a4b4af03809048ffa6542498385caab9ecdbc..391526efc854f48c1a227508470978787b60aa80 100644
--- a/tests/builtins/calloc.c
+++ b/tests/builtins/calloc.c
@@ -4,8 +4,8 @@
  STDOPT: #"-eva-no-builtins-auto -eva-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_by_stack"
  STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_fresh"
  STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_by_stack"
+ STDOPT: #"-eva-no-builtins-auto -eva-no-alloc-returns-null -eva-builtin calloc:Frama_C_calloc_imprecise"
  */
-
 #include <stdlib.h>
 #include <stdint.h>
 
diff --git a/tests/builtins/malloc.c b/tests/builtins/malloc.c
index c62203fa9ddc252a00f91fa13647a74520e169bf..af2dbc58d5b2eff3d0a49890a02bf98bbfc295c7 100644
--- a/tests/builtins/malloc.c
+++ b/tests/builtins/malloc.c
@@ -4,7 +4,7 @@
 #include <stddef.h>
 void *Frama_C_malloc_by_stack(size_t i);
 void *Frama_C_malloc_fresh(size_t i);
-
+void *Frama_C_malloc_imprecise(size_t i);
 void main(int c) {
   int x;
   int *s;
@@ -30,5 +30,10 @@ void main(int c) {
   *r = 1;
   *(r+2) = 3;
 
+  int *mw = Frama_C_malloc_imprecise(42);
+  *mw = 1;
+  int *mw2 = Frama_C_malloc_imprecise(42);
+  *mw2 = 2;
+
   //  *s = 1;
 }
diff --git a/tests/builtins/oracle/calloc.5.res.oracle b/tests/builtins/oracle/calloc.5.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..679c1f964b2efcdc39a9b52a8af80ba2a8d09bd6
--- /dev/null
+++ b/tests/builtins/oracle/calloc.5.res.oracle
@@ -0,0 +1,57 @@
+[kernel] Parsing tests/builtins/calloc.c (with preprocessing)
+[eva] Analyzing a complete application starting at main
+[eva] Computing initial state
+[eva] Initial state computed
+[eva:initial-state] Values of globals at initialization
+  nondet ∈ [--..--]
+[eva] tests/builtins/calloc.c:14: 
+  Call to builtin Frama_C_calloc_imprecise for function calloc
+[eva:malloc:imprecise] tests/builtins/calloc.c:14: Warning: 
+  allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main
+[eva] tests/builtins/calloc.c:17: 
+  Call to builtin Frama_C_calloc_imprecise for function calloc
+[eva] tests/builtins/calloc.c:20: 
+  Call to builtin Frama_C_calloc_imprecise for function calloc
+[eva] tests/builtins/calloc.c:23: 
+  Call to builtin Frama_C_calloc_imprecise for function calloc
+[eva:alarm] tests/builtins/calloc.c:26: Warning: assertion got status unknown.
+[eva:alarm] tests/builtins/calloc.c:27: Warning: assertion got status unknown.
+[eva] tests/builtins/calloc.c:30: 
+  Call to builtin Frama_C_calloc_imprecise for function calloc
+[eva:alarm] tests/builtins/calloc.c:33: Warning: assertion got status unknown.
+[eva:alarm] tests/builtins/calloc.c:34: Warning: assertion got status unknown.
+[eva:alarm] tests/builtins/calloc.c:35: Warning: assertion got status unknown.
+[eva] tests/builtins/calloc.c:38: 
+  Call to builtin Frama_C_calloc_imprecise for function calloc
+[eva] tests/builtins/calloc.c:38: Warning: 
+  calloc out of bounds: assert(nmemb * size <= SIZE_MAX)
+[eva] tests/builtins/calloc.c:40: assertion got status valid.
+[eva] Recording results for main
+[eva] done for function main
+[eva] ====== VALUES COMPUTED ======
+[eva:final-states] Values at end of function main:
+  __fc_heap_status ∈ [--..--]
+  p1 ∈ {{ &__alloc_w_main[0] }}
+  p2 ∈ {{ &__alloc_w_main[0] }}
+  p3 ∈ {{ &__alloc_w_main[0] }}
+  p4 ∈ {{ &__alloc_w_main[0] }}
+  p5 ∈ {{ (int *)&__alloc_w_main }}
+  p9001 ∈ {0}
+  __retres ∈ {0}
+[from] Computing for function main
+[from] Computing for function calloc <-main
+[from] Done for function calloc
+[from] Done for function main
+[from] ====== DEPENDENCIES COMPUTED ======
+  These dependencies hold at termination for the executions that terminate:
+[from] Function calloc:
+  __fc_heap_status FROM __fc_heap_status; nmemb; size (and SELF)
+  \result FROM __fc_heap_status; nmemb; size
+[from] Function main:
+  __fc_heap_status FROM __fc_heap_status (and SELF)
+  \result FROM __fc_heap_status
+[from] ====== END OF DEPENDENCIES ======
+[inout] Out (internal) for function main:
+    __fc_heap_status; p1; p2; p3; p4; p5; p9001; __retres
+[inout] Inputs for function main:
+    __fc_heap_status; nondet
diff --git a/tests/builtins/oracle/malloc.res.oracle b/tests/builtins/oracle/malloc.res.oracle
index ba9de96ef129ce0b44f01becf1eab69d204e5abb..6bfbf908188b5a5853ee19749c30e75bcd07d56f 100644
--- a/tests/builtins/oracle/malloc.res.oracle
+++ b/tests/builtins/oracle/malloc.res.oracle
@@ -3,6 +3,8 @@
   Neither code nor specification for function Frama_C_malloc_fresh, generating default assigns from the prototype
 [kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: 
   Neither code nor specification for function Frama_C_malloc_by_stack, generating default assigns from the prototype
+[kernel:annot:missing-spec] tests/builtins/malloc.c:8: Warning: 
+  Neither code nor specification for function Frama_C_malloc_imprecise, generating default assigns from the prototype
 [eva] Analyzing a complete application starting at main
 [eva] Computing initial state
 [eva] Initial state computed
@@ -32,6 +34,16 @@
   Frama_C_show_each: {{ &__malloc_main_l20 + {8} }}
 [eva] tests/builtins/malloc.c:27: 
   Frama_C_show_each: {{ &__malloc_main_l20 + {8} }}
+[eva] tests/builtins/malloc.c:33: Call to builtin Frama_C_malloc_imprecise
+[eva:malloc:imprecise] tests/builtins/malloc.c:33: Warning: 
+  allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main
+[eva] tests/builtins/malloc.c:33: Call to builtin Frama_C_malloc_imprecise
+[eva:alarm] tests/builtins/malloc.c:34: Warning: 
+  out of bounds write. assert \valid(mw);
+[eva] tests/builtins/malloc.c:35: Call to builtin Frama_C_malloc_imprecise
+[eva] tests/builtins/malloc.c:35: Call to builtin Frama_C_malloc_imprecise
+[eva:alarm] tests/builtins/malloc.c:36: Warning: 
+  out of bounds write. assert \valid(mw2);
 [eva] Recording results for main
 [eva] done for function main
 [eva] ====== VALUES COMPUTED ======
@@ -41,6 +53,8 @@
   p ∈ {{ (int *)&__malloc_main_l19 }}
   q ∈ {{ &__malloc_main_l20[0] }}
   r ∈ {{ &__malloc_main_l21[0] ; &__malloc_main_l21_0[0] }}
+  mw ∈ {{ (int *)&__alloc_w_main }}
+  mw2 ∈ {{ (int *)&__alloc_w_main }}
   __malloc_main_l19[bits 0 to 31] ∈ {1}
                    [4..7] ∈ UNINITIALIZED
                    [bits 64 to 95] ∈ {3}
@@ -58,3 +72,5 @@
                      [1] ∈ UNINITIALIZED
                      [2] ∈ {3}
                      [3..24] ∈ UNINITIALIZED
+  __alloc_w_main[bits 0 to 31] ∈ {1; 2} or UNINITIALIZED
+                [4..4294967295] ∈ UNINITIALIZED
diff --git a/tests/builtins/oracle/realloc_imprecise.res.oracle b/tests/builtins/oracle/realloc_imprecise.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..346a55355c0f64cf362f127e98845f8691bee8b6
--- /dev/null
+++ b/tests/builtins/oracle/realloc_imprecise.res.oracle
@@ -0,0 +1,65 @@
+[kernel] Parsing tests/builtins/realloc_imprecise.c (with preprocessing)
+[eva] Analyzing a complete application starting at main
+[eva] Computing initial state
+[eva] Initial state computed
+[eva:initial-state] Values of globals at initialization
+  v ∈ [--..--]
+[eva] tests/builtins/realloc_imprecise.c:10: 
+  Call to builtin Frama_C_malloc_imprecise for function malloc
+[eva:malloc:imprecise] tests/builtins/realloc_imprecise.c:10: Warning: 
+  allocating a single weak variable for ALL dynamic allocations via malloc/calloc/realloc: __alloc_w_main
+[eva:alarm] tests/builtins/realloc_imprecise.c:11: Warning: 
+  out of bounds write. assert \valid(p);
+[eva] tests/builtins/realloc_imprecise.c:13: 
+  Call to builtin Frama_C_realloc_imprecise for function realloc
+[eva] tests/builtins/realloc_imprecise.c:13: 
+  function realloc: precondition 'freeable' got status valid.
+[eva:malloc] tests/builtins/realloc_imprecise.c:13: 
+  weak free on bases: {__alloc_w_main}
+[eva] tests/builtins/realloc_imprecise.c:15: 
+  Call to builtin Frama_C_realloc_imprecise for function realloc
+[eva] tests/builtins/realloc_imprecise.c:15: 
+  function realloc: precondition 'freeable' got status valid.
+[eva:malloc] tests/builtins/realloc_imprecise.c:15: 
+  weak free on bases: {__alloc_w_main}
+[eva] tests/builtins/realloc_imprecise.c:16: Call to builtin free
+[eva] tests/builtins/realloc_imprecise.c:16: 
+  function free: precondition 'freeable' got status valid.
+[eva:malloc] tests/builtins/realloc_imprecise.c:16: 
+  weak free on bases: {__alloc_w_main}
+[eva] Recording results for main
+[eva] done for function main
+[eva] ====== VALUES COMPUTED ======
+[eva:final-states] Values at end of function main:
+  __fc_heap_status ∈ [--..--]
+  p ∈ {{ (int *)&__alloc_w_main }} or ESCAPINGADDR
+  pp ∈ {{ (int *)&__alloc_w_main }} or ESCAPINGADDR
+  q ∈ {{ (int *)&__alloc_w_main }} or ESCAPINGADDR
+  __alloc_w_main[bits 0 to 31] ∈ {17} or UNINITIALIZED
+                [4..4294967295] ∈ UNINITIALIZED
+[from] Computing for function main
+[from] Computing for function malloc <-main
+[from] Done for function malloc
+[from] Computing for function realloc <-main
+[from] Done for function realloc
+[from] Computing for function free <-main
+[from] Done for function free
+[from] Done for function main
+[from] ====== DEPENDENCIES COMPUTED ======
+  These dependencies hold at termination for the executions that terminate:
+[from] Function free:
+  __fc_heap_status FROM __fc_heap_status (and SELF)
+[from] Function malloc:
+  __fc_heap_status FROM __fc_heap_status; size (and SELF)
+  \result FROM __fc_heap_status; size
+[from] Function realloc:
+  __fc_heap_status FROM __fc_heap_status (and SELF)
+  \result FROM __fc_heap_status; ptr; size
+[from] Function main:
+  __fc_heap_status FROM __fc_heap_status; v (and SELF)
+  __alloc_w_main[0..3] FROM __fc_heap_status (and SELF)
+[from] ====== END OF DEPENDENCIES ======
+[inout] Out (internal) for function main:
+    __fc_heap_status; p; pp; q; r; __alloc_w_main[0..3]
+[inout] Inputs for function main:
+    __fc_heap_status; v
diff --git a/tests/builtins/realloc_imprecise.c b/tests/builtins/realloc_imprecise.c
new file mode 100644
index 0000000000000000000000000000000000000000..bd9e002b64b2fc82554c3578f90877ee93a1fa45
--- /dev/null
+++ b/tests/builtins/realloc_imprecise.c
@@ -0,0 +1,18 @@
+/* run.config*
+   STDOPT: +"-eva-builtin malloc:Frama_C_malloc_imprecise,realloc:Frama_C_realloc_imprecise"
+*/
+
+#include <stdlib.h>
+
+volatile int v;
+
+void main() {
+  int *p = malloc(sizeof(int));
+  *p = 17;
+  int *pp = p;
+  int *q = realloc(p, 2 * sizeof(int));
+  if (v) {
+    int *r = realloc(q, sizeof(int));
+    free(r);
+  }
+}