let build_elem_opt ~addrlab ~mlab elem = 
  let mk_mem_at t = 
    if Logic_utils.is_same_logic_label mlab Logic_const.here_label then t
    else Logic_const.tat (t, mlab) 
  in
  if Logic_utils.is_same_logic_label addrlab mlab then
    Some (mk_mem_at elem)
  else match elem.term_node with
    | TLval (h, off) ->
      let mk_addr_at t = Logic_const.tat (t, addrlab) in
      let rec mk_at_off off = match off with TNoOffset -> off
        | TField (f, off) -> TField (f, mk_at_off off)
        | TIndex (i, off) -> TIndex (mk_addr_at i, mk_at_off off)
      in
      let off' = mk_at_off off in
      let h' = match h with
        | TVar _ | TResult _ -> h
        | TMem p -> TMem (mk_addr_at p)
      in
      let lv' = TLval (h', off') in
      let elem' = Logic_const.term lv' elem.term_type in
      let elem' = mk_mem_at elem' in
        Some (elem')
  | _ ->
      Wp_parameters.not_yet_implemented
        "assigns left part is not a lvalue: %a" Cil.d_term elem