From 242ebe1f51e5c15299d3852b9eee89962d9a58f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Fri, 21 Feb 2020 10:38:35 +0100 Subject: [PATCH] [Eva] In abstract domains, uses [variable_kind] instead of [init_kind]. In the function [initialize_variable_using_type]. Adds a constructor [Return] to [variable_kind] for the special variable that stores the return value of a function call. --- src/plugins/value/domains/abstract_domain.mli | 23 +++++++++++-------- .../value/domains/cvalue/cvalue_domain.ml | 10 ++++---- src/plugins/value/domains/traces_domain.ml | 17 +++++++------- src/plugins/value/engine/initialization.ml | 5 ++-- src/plugins/value/engine/iterator.ml | 2 +- .../value/engine/transfer_specification.ml | 7 +++--- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/plugins/value/domains/abstract_domain.mli b/src/plugins/value/domains/abstract_domain.mli index 80047f65758..9fd9ddd2929 100644 --- a/src/plugins/value/domains/abstract_domain.mli +++ b/src/plugins/value/domains/abstract_domain.mli @@ -273,17 +273,16 @@ type 'state logic_environment = { } type variable_kind = - | Global - | Formal of kernel_function - | Local of kernel_function + | Global (** Global variable *) + | Formal of kernel_function (** Formal parameter of a function. *) + | Local of kernel_function (** Local variable of a function. *) + | Return of kernel_function (** Special variable that stores the return value + of a call from the end of the function called + back to the call site. *) (** Value for the initialization of variables. Can be either zero or top. *) type init_value = Zero | Top -(* Kind of variable being initialized by initialize_variable_using_type. *) -type init_kind = - Main_Formal | Library_Global | Spec_Return of kernel_function - (** MemExec is a global cache for the complete analysis of functions. It avoids repeating the analysis of a function in equivalent entry states. It uses an over-approximation of the locations possibly read and written @@ -407,9 +406,13 @@ module type S = sig val initialize_variable: lval -> location -> initialized:bool -> init_value -> t -> t - (** Initializes a variable according to its type. TODO: move some parts - of the cvalue implementation of this function in the generic engine. *) - val initialize_variable_using_type: init_kind -> varinfo -> t -> t + (** Initializes a variable according to its type. TODO: move some parts of the + cvalue implementation of this function in the generic engine. + The variable can be: + - a global variable on lib-entry mode. + - a formal parameter of the 'main' function. + - the return variable of a function specification. *) + val initialize_variable_using_type: variable_kind -> varinfo -> t -> t (** {3 Miscellaneous } *) diff --git a/src/plugins/value/domains/cvalue/cvalue_domain.ml b/src/plugins/value/domains/cvalue/cvalue_domain.ml index 3ff88aca356..986f01689ab 100644 --- a/src/plugins/value/domains/cvalue/cvalue_domain.ml +++ b/src/plugins/value/domains/cvalue/cvalue_domain.ml @@ -362,10 +362,9 @@ module State = struct let initialize_variable_using_type kind varinfo (state, clob) = match kind with - | Abstract_domain.Main_Formal - | Abstract_domain.Library_Global -> + | Abstract_domain.(Global | Formal _ | Local _) -> Cvalue_init.initialize_var_using_type varinfo state, clob - | Abstract_domain.Spec_Return kf -> + | Abstract_domain.Return kf -> let value = Library_functions.returned_value kf in let loc = Locations.loc_of_varinfo varinfo in Model.add_binding ~exact:true state loc value, clob @@ -396,9 +395,8 @@ module State = struct let enter_scope kind vars (state, clob) = let bind = match kind with - | Abstract_domain.Local _kf -> bind_local - | Abstract_domain.Formal _kf -> bind_local - | Abstract_domain.Global -> bind_global + | Abstract_domain.Global -> bind_global + | Abstract_domain.(Local _ | Formal _ | Return _) -> bind_local in List.fold_left bind state vars, clob diff --git a/src/plugins/value/domains/traces_domain.ml b/src/plugins/value/domains/traces_domain.ml index 69dde95e126..d7e947f267e 100644 --- a/src/plugins/value/domains/traces_domain.ml +++ b/src/plugins/value/domains/traces_domain.ml @@ -916,14 +916,15 @@ module Internal = struct let empty () = Traces.empty let initialize_variable lv _ ~initialized:_ _ state = Traces.add_trans state (Msg(Format.asprintf "initialize variable: %a" Printer.pp_lval lv )) - let initialize_variable_using_type init_kind varinfo state = + let initialize_variable_using_type var_kind varinfo state = let msg = Format.asprintf "initialize@ variable@ using@ type@ %a@ %a" - (fun fmt init_kind -> - match init_kind with - | Abstract_domain.Main_Formal -> Format.pp_print_string fmt "Main_Formal" - | Abstract_domain.Library_Global -> Format.pp_print_string fmt "Library_Global" - | Abstract_domain.Spec_Return kf -> Format.fprintf fmt "Spec_Return(%s)" (Kernel_function.get_name kf)) - init_kind + (fun fmt var_kind -> + match var_kind with + | Abstract_domain.Local _ -> Format.pp_print_string fmt "Local" + | Abstract_domain.Formal _ -> Format.pp_print_string fmt "Formal" + | Abstract_domain.Global -> Format.pp_print_string fmt "Global" + | Abstract_domain.Return kf -> Format.fprintf fmt "Return(%s)" (Kernel_function.get_name kf)) + var_kind Varinfo.pretty varinfo in Traces.add_trans state (Msg msg) @@ -1001,7 +1002,7 @@ module Internal = struct if Kernel_function.equal kf (fst (Globals.entry_point ())) then { state with main_formals = vars @ state.main_formals } else state - | Abstract_domain.Local kf -> + | Abstract_domain.(Local kf | Return kf) -> Traces.add_trans state (EnterScope (kf, vars)) let leave_scope kf vars state = diff --git a/src/plugins/value/engine/initialization.ml b/src/plugins/value/engine/initialization.ml index 7d06a16962e..fb70a7e9ae9 100644 --- a/src/plugins/value/engine/initialization.ml +++ b/src/plugins/value/engine/initialization.ml @@ -234,7 +234,7 @@ module Make initialize_var_padding vi ~local:false ~lib_entry:true state in (* Then initialize non-padding bits according to the type. *) - let kind = Abstract_domain.Library_Global in + let kind = Abstract_domain.Global in Domain.initialize_variable_using_type kind vi state in (* If needed, initializes const fields according to the initializer @@ -266,8 +266,7 @@ module Make else let var_kind = Abstract_domain.Formal kf in let state = Domain.enter_scope var_kind l state in - let init_kind = Abstract_domain.Main_Formal in - List.fold_right (Domain.initialize_variable_using_type init_kind) l state + List.fold_right (Domain.initialize_variable_using_type var_kind) l state (* Use the values supplied in [actuals] for the formals of [kf], and bind them in [state] *) diff --git a/src/plugins/value/engine/iterator.ml b/src/plugins/value/engine/iterator.ml index def379b956f..c58cdc0e60e 100644 --- a/src/plugins/value/engine/iterator.ml +++ b/src/plugins/value/engine/iterator.ml @@ -337,7 +337,7 @@ module Make_Dataflow let return_lval = Var vi_ret, NoOffset in let kstmt = Kstmt stmt in fun state -> - let kind = Abstract_domain.Local kf in + let kind = Abstract_domain.Return kf in let state = Domain.enter_scope kind [vi_ret] state in let state' = Transfer.assign state kstmt return_lval return_exp in Bottom.to_list state' diff --git a/src/plugins/value/engine/transfer_specification.ml b/src/plugins/value/engine/transfer_specification.ml index 2d62190cc61..dff7f2b618d 100644 --- a/src/plugins/value/engine/transfer_specification.ml +++ b/src/plugins/value/engine/transfer_specification.ml @@ -546,10 +546,9 @@ module Make | Some retres_vi -> (* Notify the user about missing assigns \result. *) if warn then warn_on_missing_result_assigns kinstr call.kf spec; - let kind = Abstract_domain.Local call.kf in - let state = Domain.enter_scope kind [retres_vi] state in - let init_kind = Abstract_domain.Spec_Return call.kf in - Domain.initialize_variable_using_type init_kind retres_vi state + let var_kind = Abstract_domain.Return call.kf in + let state = Domain.enter_scope var_kind [retres_vi] state in + Domain.initialize_variable_using_type var_kind retres_vi state in let states = compute_specification ~warn kinstr call.kf call.return spec state -- GitLab