let mk_mu m lval =
      let do_indir f_obj1 sh f_mu_of_mu2 =
        let f_obj2 = fun obj0 -> match sh with
          | None -> F.data_of_term (indir m (f_obj1 obj0)) 
          | Some i -> F.data_of_term (indir m (F.shift_pointer (f_obj1 obj0) i))
        in
        let f_mu_of_mu3 = fun obj0 mu3 ->
          let mu2 = F.term_of_data (F.mk_mu_sh_indir (f_obj1 obj0) sh mu3) in
          f_mu_of_mu2 obj0 (Some mu2)
        in f_obj2, f_mu_of_mu3
      in
      let rec addr_loc l = match l with
        | F.D1var (Some (vi,  Clabels.Here),_) -> cvar m vi
        | F.D1proj (l, ch) -> F.shift_epath (addr_loc l) ch
        | F.D1indir l -> l
        | _ -> unsupported "take address of unknown location: %a" pp_loc l
      in
      let rec mk_mu_rec lval = match lval with
        | F.D1null -> unsupported "assignment to NULL pointer !"
        | F.D1addr (v,_) -> v, (fun obj -> obj), (fun _obj mu -> mu)
        | F.D1depl (lv, d2) ->
            let v, f_obj1, f_mu_of_mu2 = mk_mu_rec lv in
            let f_obj2 = fun obj0 -> F.data_of_term (F.proj (f_obj1 obj0) d2) in
            let f_mu_of_mu3 = fun obj0 mu3 ->
              let mu2 = F.term_of_data (F.mk_mu (f_obj1 obj0) d2 mu3) in
              f_mu_of_mu2 obj0 (Some mu2)
            in
            v, f_obj2, f_mu_of_mu3
        | F.D1indir (lv) ->
            let v, f_obj1, f_mu_of_mu2 = mk_mu_rec lv in
            let f_obj2, f_mu_of_mu3 = do_indir f_obj1 None f_mu_of_mu2 in
            v, f_obj2, f_mu_of_mu3
        |  F.D1var (Some (v,  Clabels.Here),_) -> (* == D1indir (D1addr) *)
             let f_obj1 obj0 = obj0 in
             let f_mu_of_mu2 _o mu = mu in
             let f_obj2, f_mu_of_mu3 = do_indir f_obj1 None f_mu_of_mu2 in
             v, f_obj2, f_mu_of_mu3
        | F.D1proj (lv, ch) -> (* D1proj (x,ch) == D1indir (D1depl (&x,ch)) *)
            let lv_depl = F.shift_epath (addr_loc lv) ch in
            let v, f_obj1, f_mu_of_mu2 = mk_mu_rec lv_depl in
            let f_obj2, f_mu_of_mu3 = do_indir f_obj1 None f_mu_of_mu2 in
            v, f_obj2, f_mu_of_mu3
        | F.D1shift (lv, i) -> (* [lv] must be something like [*p] :
                                  process shift + indir in one step *)

            let p = addr_loc lv in
            let v, f_obj1, f_mu_of_mu2 = mk_mu_rec p in 
            let f_obj2, f_mu_of_mu3 = do_indir f_obj1 (Some i) f_mu_of_mu2 in
            v, f_obj2, f_mu_of_mu3
        | _ -> unsupported "assignment to unknown location: %a" pp_loc lval
      in mk_mu_rec lval