diff --git a/src/plugins/wp/MemVar.ml b/src/plugins/wp/MemVar.ml
index 70e14713b79ab169f32bdd588bd4b1572ee070d2..03cb5d2c3c27552b5c338bfbcd1b99146efd9a75 100644
--- a/src/plugins/wp/MemVar.ml
+++ b/src/plugins/wp/MemVar.ml
@@ -516,8 +516,8 @@ struct
   type mem =
     | CVAL (* By-Value variable *)
     | CREF (* By-Ref variable *)
-    | CTXT (* In-context pointer *)
-    | CARR (* In-context array *)
+    | CTXT of MemoryContext.validity (* In-context pointer *)
+    | CARR of MemoryContext.validity (* In-context array *)
     | HEAP (* In-heap variable *)
 
   type loc =
@@ -562,8 +562,8 @@ struct
   let vtype m x =
     match m with
     | CVAL | HEAP -> x.vtype
-    | CTXT | CREF -> Cil.typeOf_pointed x.vtype
-    | CARR -> Ast_info.array_type (Cil.typeOf_pointed x.vtype)
+    | CTXT _ | CREF -> Cil.typeOf_pointed x.vtype
+    | CARR _ -> Ast_info.array_type (Cil.typeOf_pointed x.vtype)
 
   let vobject m x = Ctypes.object_of (vtype m x)
 
@@ -592,8 +592,8 @@ struct
   let pp_mem fmt = function
     | CVAL -> Format.pp_print_string fmt "var"
     | CREF -> Format.pp_print_string fmt "ref"
-    | CTXT -> Format.pp_print_string fmt "ptr"
-    | CARR -> Format.pp_print_string fmt "arr"
+    | CTXT _ -> Format.pp_print_string fmt "ptr"
+    | CARR _ -> Format.pp_print_string fmt "arr"
     | HEAP -> Format.pp_print_string fmt "mem"
 
   (* re-uses strings that are used into the description of -wp-xxx-vars *)
@@ -633,6 +633,35 @@ struct
     | ByAddr -> Val(HEAP,x,[])
     | InContext _ | InArray _ | ByRef -> Ref x
 
+  (* -------------------------------------------------------------------------- *)
+  (* ---  Nullable locations                                                --- *)
+  (* -------------------------------------------------------------------------- *)
+
+  module Nullable = WpContext.Generator(Varinfo)
+      (struct
+        let name = "MemVar.Nullable"
+        type key = varinfo
+        type data = lfun
+
+        let compile v =
+          let result = t_addr () in
+          let lfun = Lang.generated_f ~result "pointer_%s" v.vname in
+          let cluster =
+            Definitions.cluster ~id:"Globals" ~title:"Context pointers" ()
+          in
+          Definitions.define_symbol {
+            d_lfun = lfun ;
+            d_types = 0 ;
+            d_params = [] ;
+            d_definition = Definitions.Logic result ;
+            d_cluster = cluster
+          } ;
+          lfun
+      end)
+
+  let nullable_address v =
+    Lang.F.e_fun (Nullable.get v) []
+
   (* -------------------------------------------------------------------------- *)
   (* ---  Lifting                                                           --- *)
   (* -------------------------------------------------------------------------- *)
@@ -644,7 +673,11 @@ struct
   let mseq_of_seq seq = { pre = seq.pre.mem ; post = seq.post.mem }
 
   let mloc_of_path m x ofs =
-    List.fold_left moffset (M.cvar (vbase m x)) ofs
+    let l = match m with
+      | CTXT Nullable | CARR Nullable -> M.pointer_loc @@ nullable_address x
+      | _ -> M.cvar (vbase m x)
+    in
+    List.fold_left moffset l ofs
 
   let mloc_of_loc = function
     | Loc l -> l
@@ -731,8 +764,8 @@ struct
     | Ref x ->
         begin match V.param x with
           | ByRef       -> Sigs.Loc(Val(CREF,x,[]))
-          | InContext _ -> Sigs.Loc(Val(CTXT,x,[]))
-          | InArray _   -> Sigs.Loc(Val(CARR,x,[]))
+          | InContext n -> Sigs.Loc(Val(CTXT n,x,[]))
+          | InArray n   -> Sigs.Loc(Val(CARR n,x,[]))
           | NotUsed | ByAddr | ByValue | ByShift -> assert false
         end
     | Val((CREF|CVAL),x,ofs) ->
@@ -741,7 +774,7 @@ struct
         Cvalues.map_value
           (fun l -> Loc l)
           (M.load sigma.mem obj l)
-    | Val((CTXT|CARR|HEAP) as m,x,ofs) ->
+    | Val((CTXT _|CARR _|HEAP) as m,x,ofs) ->
         Cvalues.map_value
           (fun l -> Loc l)
           (M.load sigma.mem obj (mloc_of_path m x ofs))
@@ -772,7 +805,7 @@ struct
     | Val((CREF|CVAL),x,ofs) ->
         let init = Cvalues.initialized_obj obj in
         (memvar_stored seq obj l v) :: (memvar_set_init seq x ofs init)
-    | Val((CTXT|CARR|HEAP) as m,x,ofs) ->
+    | Val((CTXT _|CARR _|HEAP) as m,x,ofs) ->
         M.stored (mseq_of_seq seq) obj (mloc_of_path m x ofs) v
     | Loc l ->
         M.stored (mseq_of_seq seq) obj l v
@@ -789,6 +822,8 @@ struct
 
   let is_null = function
     | Loc l -> M.is_null l
+    | Val ((CTXT Nullable|CARR Nullable)as m,x,ofs) ->
+        M.is_null (mloc_of_path m x ofs)
     | Ref _ | Val _ -> F.p_false
 
   let rec offset = function
@@ -830,7 +865,7 @@ struct
   exception ShiftMismatch
 
   let is_heap_allocated = function
-    | CREF | CVAL -> false | HEAP | CTXT | CARR -> true
+    | CREF | CVAL -> false | HEAP | CTXT _ | CARR _ -> true
 
   let shift_mismatch l =
     Wp_parameters.fatal "Invalid shift : %a" pretty l
@@ -938,7 +973,9 @@ struct
     else
       match mem with
       | CVAL | HEAP -> p_bool (ALLOC.value sigma.alloc x)
-      | CREF | CTXT | CARR -> p_true
+      | CREF | CTXT Valid | CARR Valid -> p_true
+      | CTXT Nullable | CARR Nullable ->
+          p_not @@ M.is_null (mloc_of_path mem x [])
 
   (* segment *)
 
@@ -1220,6 +1257,20 @@ struct
         in
         List.map uninitialized xs
 
+  let scope_nullable xs =
+    let predicate_is_nullable v =
+      Option.map
+        (fun m ->
+           let addr = nullable_address v in
+           p_or
+             (M.is_null @@ M.pointer_loc addr)
+             (p_equal (M.pointer_val @@ M.cvar (vbase m v)) addr))
+        (match V.param v with
+         | InContext Nullable -> Some (CTXT Nullable)
+         | InArray Nullable -> Some (CARR Nullable)
+         | _ -> None)
+    in
+    List.filter_map predicate_is_nullable xs
 
   let scope seq scope xs =
     let xm = List.filter is_mem xs in
@@ -1227,7 +1278,8 @@ struct
     let hmem = M.scope smem scope xm in
     let hvars = scope_vars seq scope xs in
     let hinit = scope_init seq scope xs in
-    hvars @ hinit @ hmem
+    let hcontext = scope_nullable xs in
+    hvars @ hinit @ hmem @ hcontext
 
   let global sigma p = M.global sigma.mem p
 
@@ -1362,7 +1414,7 @@ struct
     | Val((CVAL|CREF),_,_) as vloc ->
         let v = Lang.freshvar ~basename:"v" (Lang.tau_of_object obj) in
         memvar_assigned seq obj vloc (e_var v)
-    | Val((HEAP|CTXT|CARR) as m,x,ofs) ->
+    | Val((HEAP|CTXT _|CARR _) as m,x,ofs) ->
         M.assigned (mseq_of_seq seq) obj (Sloc (mloc_of_path m x ofs))
     | Loc l ->
         M.assigned (mseq_of_seq seq) obj (Sloc l)
@@ -1384,7 +1436,7 @@ struct
         in
         let obj = get_obj (Ctypes.object_of x.vtype) ofs in
         memvar_assigned seq obj vloc (e_var v)
-    | Val((HEAP|CTXT|CARR) as m,x,ofs) ->
+    | Val((HEAP|CTXT _|CARR _) as m,x,ofs) ->
         let l = mloc_of_path m x ofs in
         M.assigned (mseq_of_seq seq) obj (Sarray(l,elt,n))
     | Loc l ->
@@ -1395,7 +1447,7 @@ struct
     | Ref x -> noref ~op:"assigns to" x
     | Loc l ->
         M.assigned (mseq_of_seq seq) obj (Srange(l,elt,a,b))
-    | Val((HEAP|CTXT|CARR) as m,x,ofs) ->
+    | Val((HEAP|CTXT _|CARR _) as m,x,ofs) ->
         M.assigned (mseq_of_seq seq) obj (Srange(mloc_of_path m x ofs,elt,a,b))
     | Val((CVAL|CREF) as m,x,ofs) ->
         let k = Lang.freshvar ~basename:"k" Qed.Logic.Int in
@@ -1409,7 +1461,7 @@ struct
     | Ref x -> noref ~op:"assigns to" x
     | Loc l ->
         M.assigned (mseq_of_seq seq) obj (Sdescr(xs,l,p))
-    | Val((HEAP|CTXT|CARR) as m,x,ofs) ->
+    | Val((HEAP|CTXT _|CARR _) as m,x,ofs) ->
         M.assigned (mseq_of_seq seq) obj (Sdescr(xs,mloc_of_path m x ofs,p))
     | Val((CVAL|CREF) as m,x,ofs) ->
         (monotonic_initialized_genset seq xs m x ofs p) @
@@ -1479,9 +1531,15 @@ struct
         Fseg(x,range ofs obj a b)
 
     (* in M: *)
-    | Rloc(obj,Val((CTXT|CARR|HEAP) as m,x,ofs)) ->
+    (* First intercept nullable context *)
+    | Rloc(obj,Val((CTXT Nullable|CARR Nullable) as m,x,ofs)) ->
+        Lseg(Rloc(obj, mloc_of_path m x ofs))
+    | Rrange(Val((CTXT Nullable|CARR Nullable) as m,x,ofs),obj,a,b) ->
+        Lseg(Rrange(mloc_of_path m x ofs, obj, a, b))
+
+    | Rloc(obj,Val((CTXT _|CARR _|HEAP) as m,x,ofs)) ->
         Mseg(Rloc(obj,mloc_of_path m x ofs),x,delta obj x ofs)
-    | Rrange(Val((CTXT|CARR|HEAP) as m,x,ofs),obj,a,b) ->
+    | Rrange(Val((CTXT _|CARR _|HEAP) as m,x,ofs),obj,a,b) ->
         Mseg(Rrange(mloc_of_path m x ofs,obj,a,b),x,range ofs obj a b)
 
   (* -------------------------------------------------------------------------- *)
@@ -1556,7 +1614,7 @@ struct
           else []
         in
         Heap.Set.of_list ((Var x) :: init)
-    | Loc _ | Val((CTXT|CARR|HEAP),_,_) ->
+    | Loc _ | Val((CTXT _|CARR _|HEAP),_,_) ->
         M.Heap.Set.fold
           (fun m s -> Heap.Set.add (Mem m) s)
           (M.domain obj (mloc_of_loc l)) Heap.Set.empty
diff --git a/src/plugins/wp/tests/wp_plugin/oracle/nullable.res.oracle b/src/plugins/wp/tests/wp_plugin/oracle/nullable.res.oracle
index 12cea0526fdaa9a6ed262bf1cb2926506559310d..5ce753cddf769def9bead79590d10b27423dacc9 100644
--- a/src/plugins/wp/tests/wp_plugin/oracle/nullable.res.oracle
+++ b/src/plugins/wp/tests/wp_plugin/oracle/nullable.res.oracle
@@ -8,7 +8,7 @@
 ------------------------------------------------------------
 
 Goal Check 'must_fail' (file tests/wp_plugin/nullable.i, line 14):
-Assume { (* Then *) Have: G_p_24 = 0. }
+Assume { (* Then *) Have: null = pointer_p. }
 Prove: false.
 
 ------------------------------------------------------------