let rec data_of_assignable env t=
    match t.term_node with

    | TLval (TVar{lv_origin=Some x}, off) ->
        begin
          match xvar_of_varinfo env x with
            | MemVar -> snd (gaddress_of_cvar env  x off)
            | PrmVar v -> Value v
        end
    | TLval (TMem e, off) ->
        snd (gaddress_of_mem env e off)
    | TAddrOf _lv -> WpLog.fatal "Unexpected address value"

    | TStartOf (TVar{lv_origin=Some x}, off)  ->
        begin
          match xvar_of_varinfo env x with
            | MemVar -> gstartof_cvar env x off
            | PrmVar v -> gstartof_value env x.vtype v off
        end

    | TStartOf (TMem e, off) -> gstartof_mem env e off

    | Tempty_set  | TLval (TResult _, _ )-> List []

    | Tat(t ,lab) -> data_of_assignable (env_at env (c_label lab)) t
    | Told t -> data_of_assignable (env_at env Pre) t

    | TBinOp((IndexPI | PlusPI),a,b) ->
        data_shift
          (kind_of a.term_type) (data_of_term env a)
          (kind_of b.term_type) (data_of_term env b)
          ~is_pos:true

    | TBinOp (MinusPI,a,b) ->
        data_shift
          (kind_of a.term_type) (data_of_term env a)
          (kind_of b.term_type) (data_of_term env b)
          ~is_pos:false

    | Tunion ts -> union_map (data_of_assignable env) ts
    | Tinter (t::ts) ->
        let f t = set_of (data_of_assignable env t) in
        Set(List.fold_left
              (fun s t -> D.inter s (f t)) (f t) ts)
    | Tinter [] -> WpLog.fatal "empty intersection"

    | TStartOf (TResult _, _ )
    | Tlet (_, _) | Tcomprehension (_, _, _)
    | Tif (_, _, _) | Tapp (_, _, _) | TCastE (_, _)

        -> WpLog.not_yet_implemented "assignation of (%a)"
        !Ast_printer.d_term t

    | TLval (TVar {lv_origin=None}, _)
    | TStartOf (TVar {lv_origin=None}, _)
    | Trange (_, _)|Ttype _|Ttypeof _|TCoerceE (_, _)|TCoerce (_, _)
    | TUpdate (_, _, _)|Tblock_length _
    | TDataCons (_, _)|Tlambda (_, _)
    | TUnOp (_, _)|TAlignOfE _|TAlignOf _|TSizeOfStr _|TSizeOfE _|TSizeOf _
    | TConst _ | Tnull | Tbase_addr _
    | TBinOp(
        (LOr|LAnd|BOr|BXor|BAnd|Ne|Eq|Ge|Le|Gt|Lt|
             Shiftrt|Shiftlt|Mod|Div|Mult|
                 MinusPP|MinusA|PlusA),_,_)
      -> WpLog.fatal "not assignable terms"