From cb9a91334500d8ae8ba101f85e1d60aa2f9dbc70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Mon, 30 Nov 2020 10:26:32 +0100 Subject: [PATCH] [Eva] Adds [replace_base] in abstract locations. Applies the substitution of local and formal variables to the copy of variables in recursive calls. --- src/plugins/value/engine/transfer_stmt.ml | 9 ++++++--- .../value/values/abstract_location.mli | 2 ++ src/plugins/value/values/main_locations.ml | 2 ++ src/plugins/value_types/precise_locs.ml | 19 +++++++++++++++++++ src/plugins/value_types/precise_locs.mli | 2 ++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/plugins/value/engine/transfer_stmt.ml b/src/plugins/value/engine/transfer_stmt.ml index eaaaca8f673..8cdbc6d4dff 100644 --- a/src/plugins/value/engine/transfer_stmt.ml +++ b/src/plugins/value/engine/transfer_stmt.ml @@ -553,21 +553,24 @@ module Make (Abstract: Abstractions.Eva) = struct in {kf; arguments; rest; return; } - let replace_value substitution = function + let replace_value visitor substitution = function | Assign value -> Assign (Value.replace_base substitution value) | Copy (loc, flagged) -> let v = flagged.v >>-: Value.replace_base substitution in let flagged = { flagged with v } in - (* TODO: replace base in [loc] *) + let lloc = Location.replace_base substitution loc.lloc in + let lval = Visitor.visitFramacLval visitor loc.lval in + let loc = { loc with lval; lloc } in Copy (loc, flagged) let replace_recursive_call recursion call = let tbl = VarHashtbl.create 9 in List.iter (fun (v1, v2) -> VarHashtbl.add tbl v1 v2) recursion.substitution; let visitor = substitution_visitor tbl in + let base_substitution = recursion.base_substitution in let replace_arg argument = let concrete = Visitor.visitFramacExpr visitor argument.concrete in - let avalue = replace_value recursion.base_substitution argument.avalue in + let avalue = replace_value visitor base_substitution argument.avalue in { argument with concrete; avalue } in let arguments = List.map replace_arg call.arguments in diff --git a/src/plugins/value/values/abstract_location.mli b/src/plugins/value/values/abstract_location.mli index df2247048be..00d64bc5f32 100644 --- a/src/plugins/value/values/abstract_location.mli +++ b/src/plugins/value/values/abstract_location.mli @@ -44,6 +44,8 @@ module type S = sig val to_value : location -> value val size : location -> Int_Base.t + val replace_base: Base.substitution -> location -> location + (** {3 Alarms } *) (** These functions are used to create the alarms that report undesirable diff --git a/src/plugins/value/values/main_locations.ml b/src/plugins/value/values/main_locations.ml index 7aab78471df..7dd75133117 100644 --- a/src/plugins/value/values/main_locations.ml +++ b/src/plugins/value/values/main_locations.ml @@ -62,6 +62,8 @@ module PLoc = struct else `Unknown (l1, l2) else `True + let replace_base = Precise_locs.replace_base + (* ------------------------------------------------------------------------ *) (* Offsets *) (* ------------------------------------------------------------------------ *) diff --git a/src/plugins/value_types/precise_locs.ml b/src/plugins/value_types/precise_locs.ml index 63faec349a5..905339d0fd2 100644 --- a/src/plugins/value_types/precise_locs.ml +++ b/src/plugins/value_types/precise_locs.ml @@ -263,6 +263,25 @@ let loc_top = { } let is_top_loc pl = equal_loc loc_top pl +let replace_base substitution po = + match po.loc with + | PLBottom -> po + | PLLoc loc -> + let modified, loc = Location_Bits.replace_base substitution loc in + if modified then { po with loc = PLLoc loc } else po + | PLVarOffset (base, offset) -> + let set = Base.Hptset.singleton base in + let modified, set = Base.Hptset.replace substitution set in + if modified then + let base = Option.get (Base.Hptset.contains_single_elt set) in + { po with loc = PLVarOffset (base, offset) } + else po + | PLLocOffset (loc, offset) -> + let modified, loc = Location_Bits.replace_base substitution loc in + if modified + then { po with loc = PLLocOffset (loc, offset) } + else po + let rec fold_offset f po acc = match po with | POBottom -> f Ival.bottom acc diff --git a/src/plugins/value_types/precise_locs.mli b/src/plugins/value_types/precise_locs.mli index ba93233b11a..cdff5d94de1 100644 --- a/src/plugins/value_types/precise_locs.mli +++ b/src/plugins/value_types/precise_locs.mli @@ -84,6 +84,8 @@ val is_bottom_loc: precise_location -> bool val loc_top : precise_location val is_top_loc: precise_location -> bool +val replace_base: Base.substitution -> precise_location -> precise_location + val fold: (Locations.location -> 'a -> 'a) -> precise_location -> 'a -> 'a -- GitLab