|
|
@ -315,24 +315,50 @@ module PulseTransferFunctions = struct
|
|
|
|
let* astate, (rhs_addr, rhs_history) =
|
|
|
|
let* astate, (rhs_addr, rhs_history) =
|
|
|
|
PulseOperations.eval NoAccess loc rhs_exp astate
|
|
|
|
PulseOperations.eval NoAccess loc rhs_exp astate
|
|
|
|
in
|
|
|
|
in
|
|
|
|
let* astate, lhs_addr_hist = PulseOperations.eval Write loc lhs_exp astate in
|
|
|
|
let* is_structured, ls_astate_lhs_addr_hist =
|
|
|
|
let* astate =
|
|
|
|
if Config.pulse_isl then PulseOperations.eval_structure_isl Write loc lhs_exp astate
|
|
|
|
PulseOperations.write_deref loc ~ref:lhs_addr_hist
|
|
|
|
else
|
|
|
|
~obj:(rhs_addr, event :: rhs_history)
|
|
|
|
let* astate, lhs_addr_hist = PulseOperations.eval Write loc lhs_exp astate in
|
|
|
|
astate
|
|
|
|
Ok (false, [(astate, lhs_addr_hist)])
|
|
|
|
in
|
|
|
|
|
|
|
|
let astate =
|
|
|
|
|
|
|
|
if Topl.is_deep_active () then topl_store_step loc ~lhs:lhs_exp ~rhs:rhs_exp astate
|
|
|
|
|
|
|
|
else astate
|
|
|
|
|
|
|
|
in
|
|
|
|
in
|
|
|
|
match lhs_exp with
|
|
|
|
let write_function lhs_addr_hist astate =
|
|
|
|
| Lvar pvar when Pvar.is_return pvar ->
|
|
|
|
if is_structured then
|
|
|
|
|
|
|
|
PulseOperations.write_deref_biad_isl loc ~ref:lhs_addr_hist Dereference
|
|
|
|
|
|
|
|
~obj:(rhs_addr, event :: rhs_history)
|
|
|
|
|
|
|
|
astate
|
|
|
|
|
|
|
|
else
|
|
|
|
let+ astate =
|
|
|
|
let+ astate =
|
|
|
|
PulseOperations.check_address_escape loc proc_desc rhs_addr rhs_history astate
|
|
|
|
PulseOperations.write_deref loc ~ref:lhs_addr_hist
|
|
|
|
|
|
|
|
~obj:(rhs_addr, event :: rhs_history)
|
|
|
|
|
|
|
|
astate
|
|
|
|
in
|
|
|
|
in
|
|
|
|
[astate]
|
|
|
|
[astate]
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let* astates =
|
|
|
|
|
|
|
|
List.fold_result ls_astate_lhs_addr_hist ~init:[]
|
|
|
|
|
|
|
|
~f:(fun acc_astates (astate, lhs_addr_hist) ->
|
|
|
|
|
|
|
|
match (Config.pulse_isl, astate.AbductiveDomain.isl_status) with
|
|
|
|
|
|
|
|
| false, _ | true, ISLOk ->
|
|
|
|
|
|
|
|
let+ astates = write_function lhs_addr_hist astate in
|
|
|
|
|
|
|
|
List.rev_append astates acc_astates
|
|
|
|
|
|
|
|
| true, ISLError ->
|
|
|
|
|
|
|
|
Ok (astate :: acc_astates) )
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let astates =
|
|
|
|
|
|
|
|
if Topl.is_deep_active () then
|
|
|
|
|
|
|
|
List.map astates ~f:(fun astate ->
|
|
|
|
|
|
|
|
topl_store_step loc ~lhs:lhs_exp ~rhs:rhs_exp astate )
|
|
|
|
|
|
|
|
else astates
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
match lhs_exp with
|
|
|
|
|
|
|
|
| Lvar pvar when Pvar.is_return pvar ->
|
|
|
|
|
|
|
|
List.fold_result astates ~init:[] ~f:(fun acc astate ->
|
|
|
|
|
|
|
|
let+ astate =
|
|
|
|
|
|
|
|
PulseOperations.check_address_escape loc proc_desc rhs_addr rhs_history astate
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
astate :: acc )
|
|
|
|
| _ ->
|
|
|
|
| _ ->
|
|
|
|
Ok [astate]
|
|
|
|
Ok astates
|
|
|
|
in
|
|
|
|
in
|
|
|
|
report_on_error analysis_data result
|
|
|
|
report_on_error analysis_data result
|
|
|
|
| Prune (condition, loc, _is_then_branch, _if_kind) ->
|
|
|
|
| Prune (condition, loc, _is_then_branch, _if_kind) ->
|
|
|
|