let build_guard asgn_cvar ptr p = 
  let asgn_lvar = WpFol.cvar_to_folvar asgn_cvar in
  let v, p = Fol.fresh_var_in_pred M.prop_in_data asgn_lvar p in
  let direct_asgn = match ptr with
    | Fol.Tdata (E1addr _) | Fol.Tdata (E1depl _) -> true
    | _ -> false (* TODO : check direct_asgn detection *)
  in
    Wp_parameters.debug ~level:2 "guard on modification of *(%a) (%s)" 
      pp_exp1 ptr (if direct_asgn then "direct" else "indirect");
  let guard = try
    let l = get_read_addr (not direct_asgn) p in
    let add g p = 
      Wp_parameters.debug ~level:2 "guard on %a" pp_exp1 p;
      Fol.pand ((Why_ops.disj_pointer p ptr), g) 
    in
      List.fold_left add Fol.Ptrue l
    with UnknownGuard (e, msg) -> 
      Wp_parameters.warning "problem with guard on %a (%s)" pp_exp1 e msg;
      let new_n () = 
        incr guard_counter; 
        Fol.ConstInt (string_of_int !guard_counter) 
      in Fol.papp ("guard", [Fol.Tconst (new_n ()); ptr]) 
  in v, guard, p