Skip to content
Snippets Groups Projects
Commit 0b3a9943 authored by David Bühler's avatar David Bühler
Browse files

[Eva] Fixes locals_scoping and the cvalue domain on mutually recursive calls.

parent 6b5a0947
No related branches found
No related tags found
No related merge requests found
...@@ -230,31 +230,55 @@ module State = struct ...@@ -230,31 +230,55 @@ module State = struct
Cvalue_transfer.assume stmt expr positive valuation s >>-: fun s -> Cvalue_transfer.assume stmt expr positive valuation s >>-: fun s ->
s, clob s, clob
let start_recursive_call recursion (state, clob) = let start_recursive_call stmt call recursion (state, clob) =
let direct =
try
let kf = Kernel_function.find_englobing_kf stmt in
Kernel_function.equal kf call.kf
with Not_found -> false (* Should not happen *)
in
let state = Model.remove_variables recursion.withdrawal state in let state = Model.remove_variables recursion.withdrawal state in
let state = Model.replace_base recursion.base_substitution state in let state = Model.replace_base recursion.base_substitution state in
Locals_scoping.substitute recursion.base_substitution clob state let clob = if direct then clob else Locals_scoping.top () in
let state, set =
Locals_scoping.substitute recursion.base_substitution clob state
in
Locals_scoping.remember_bases_with_locals clob (Base.SetLattice.inject set);
state
let start_call stmt call recursion valuation (state, clob) = let start_call stmt call recursion valuation (state, clob) =
let state = let state =
match recursion with match recursion with
| None -> state | None -> state
| Some recursion -> start_recursive_call recursion (state, clob) | Some recursion -> start_recursive_call stmt call recursion (state, clob)
in in
Cvalue_transfer.start_call stmt call recursion valuation state Cvalue_transfer.start_call stmt call recursion valuation state
>>-: fun state -> state, Locals_scoping.bottom () >>-: fun state -> state, Locals_scoping.bottom ()
let finalize_recursive_call ~pre recursion (state, clob) = let finalize_recursive_call stmt call ~pre recursion state =
let direct =
try
let kf = Kernel_function.find_englobing_kf stmt in
Kernel_function.equal kf call.kf
with Not_found -> false (* Should not happen *)
in
let pre, clob = pre in
let shape = Base.Hptset.shape recursion.base_withdrawal in let shape = Base.Hptset.shape recursion.base_withdrawal in
let inter = Cvalue.Model.filter_by_shape shape pre in let inter = Cvalue.Model.filter_by_shape shape pre in
let state = Cvalue.Model.merge ~into:state inter in let state = Cvalue.Model.merge ~into:state inter in
let state = Model.replace_base recursion.base_substitution state in let state = Model.replace_base recursion.base_substitution state in
Locals_scoping.substitute recursion.base_substitution clob state, clob let clob = if direct then clob else Locals_scoping.top () in
let state, _set =
Locals_scoping.substitute recursion.base_substitution clob state
in
state
let finalize_call stmt call recursion ~pre ~post = let finalize_call stmt call recursion ~pre ~post =
let pre, clob = pre in
let post = Extlib.opt_fold (finalize_recursive_call ~pre) recursion post in
let (post, post_clob) = post in let (post, post_clob) = post in
let post =
Extlib.opt_fold (finalize_recursive_call stmt call ~pre) recursion post
in
let (pre, clob) = pre in
Locals_scoping.(remember_bases_with_locals clob post_clob.clob); Locals_scoping.(remember_bases_with_locals clob post_clob.clob);
Cvalue_transfer.finalize_call stmt call recursion ~pre ~post Cvalue_transfer.finalize_call stmt call recursion ~pre ~post
>>-: fun state -> >>-: fun state ->
......
...@@ -127,32 +127,32 @@ let make_escaping_fundec fundec clob vars state = ...@@ -127,32 +127,32 @@ let make_escaping_fundec fundec clob vars state =
in in
make_escaping ~exact:true ~escaping ~on_escaping ~within:clob.clob state make_escaping ~exact:true ~escaping ~on_escaping ~within:clob.clob state
let substitute substitution clob state = let substitute substitution clob state =
(* Clean [offsm], and bind it to [base] if it is modified. *) (* Apply the [substitution] to [offsm]. If it is modified, bind the new
let replace_offsm base offsm state = offsetmap to [base] in [state], and add the [base] to [set]. *)
let replace_offsm base offsm (state, set) =
let f v = snd (Cvalue.V_Or_Uninitialized.replace_base substitution v) in let f v = snd (Cvalue.V_Or_Uninitialized.replace_base substitution v) in
let offsm' = Cvalue.V_Offsetmap.map_on_values f offsm in let offsm' = Cvalue.V_Offsetmap.map_on_values f offsm in
if Cvalue.V_Offsetmap.equal offsm' offsm if Cvalue.V_Offsetmap.equal offsm' offsm
then state then state, set
else Cvalue.Model.add_base base offsm' state else Cvalue.Model.add_base base offsm' state, Base.Hptset.add base set
in in
(* Clean the offsetmap bound to [base] in [state] *) (* Apply the substitution to the offsetmap bound to [base] in [state] *)
let replace_base base state = let replace_base base acc =
try match Cvalue.Model.find_base base state with
match Cvalue.Model.find_base base state with | `Value offsm -> replace_offsm base offsm acc
| `Top | `Bottom -> state | `Top | `Bottom -> acc
| `Value offsm -> replace_offsm base offsm state | exception Not_found -> acc
with Not_found -> state
in in
let acc = state, Base.Hptset.empty in
(* Iterate on all the bases that might contain a variable to substitute *) (* Iterate on all the bases that might contain a variable to substitute *)
try Base.SetLattice.fold replace_base clob.clob (replace_base Base.null state) try Base.SetLattice.fold replace_base clob.clob (replace_base Base.null acc)
with Abstract_interp.Error_Top -> with Abstract_interp.Error_Top ->
(* [clob] is too imprecise. Iterate on the entire memory state instead, (* [clob] is too imprecise. Iterate on the entire memory state instead,
which is much slower. *) which is much slower. *)
match state with match state with
| Cvalue.Model.Top | Cvalue.Model.Bottom -> state | Cvalue.Model.Top | Cvalue.Model.Bottom -> acc
| Cvalue.Model.Map map -> Cvalue.Model.fold replace_offsm map state | Cvalue.Model.Map map -> Cvalue.Model.fold replace_offsm map acc
(* (*
Local Variables: Local Variables:
......
...@@ -71,7 +71,8 @@ val make_escaping_fundec: ...@@ -71,7 +71,8 @@ val make_escaping_fundec:
function, in which case a different warning is emitted. *) function, in which case a different warning is emitted. *)
val substitute: val substitute:
Base.substitution -> clobbered_set -> Cvalue.Model.t -> Cvalue.Model.t Base.substitution -> clobbered_set -> Cvalue.Model.t ->
Cvalue.Model.t * Base.Hptset.t
(* (*
Local Variables: Local Variables:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment