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