let get_read_addr with_direct p =
let add d acc =
if logic_data d then
(debug3 "[get_read_addr] ignore access to logic data %a" F.pp_data d;
acc)
else
if with_direct || not (direct_lval d) then add_unique F.eq_data d acc
else
(debug3 "[get_read_addr] ignore direct access to %a" F.pp_data d; acc)
in
let do_var acc (v_opt, fv) = match v_opt with
| Some (vi, _l) ->
add (F.addr vi (F.tau_of_var fv)) acc
| None -> debug3 "get_read_addr : ignore logic variable %a" F.pp_var fv;
acc
in
let rec do_path do_exp acc ch = match ch with
| F.Pfield _ -> acc
| F.Pidx i -> do_exp acc i
and do_data do_exp acc d =
let frec = do_data do_exp in
match d with
| F.D1null | F.D1addr _ -> acc
| F.D1base p -> frec acc p
| F.D1var (v, fv) -> do_var acc (v, fv)
| F.D1proj (s, ch) ->
let acc =
try
let p = F.addr_of_data d in
let acc = add p acc in
frec acc p
with Not_found -> do_path do_exp (frec acc s) ch
in acc
| F.D1depl (ps, F.Pfield _) -> frec acc ps
| F.D1depl (p, F.Pidx i) | F.D1shift (p, i) ->
let acc = do_exp acc i in frec acc p
| F.D1indir p ->
let acc = match frec [] p with
| [] -> acc
| accp -> List.fold_left (fun acc d -> add d acc) acc accp
in add p acc
| F.D1mu (s, F.Pfield _f, x) ->
let acc = match x with Some x -> do_exp acc x | None -> acc in
frec acc s
| F.D1mu (t, F.Pidx i, x) ->
let acc = match x with Some x -> do_exp acc x | None -> acc in
let acc = do_exp acc i in
frec acc t
| F.D1muRange (t, x) ->
let acc = do_exp acc x in
frec acc t
| F.D1muI _ | F.D1muIrange _ ->
unsupported "[get_read_addr] of %a" F.pp_data d
in
let ptrs = F.visit_data_in_pred ~all:false do_data [] p in
ptrs