From dbdee5395c459722d0fb8187f9cb241ee10c4da4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr> Date: Tue, 20 Apr 2021 13:51:01 +0200 Subject: [PATCH] [Eva] Adds the [callstack] in the [Eval.call] record built by transfer_stmt. --- src/plugins/value/engine/compute_functions.ml | 4 +++- src/plugins/value/engine/recursion.ml | 4 ++-- src/plugins/value/engine/transfer_stmt.ml | 3 ++- src/plugins/value/eval.ml | 5 +++++ src/plugins/value/eval.mli | 13 +++++++++++++ src/plugins/value/utils/value_util.ml | 6 +----- src/plugins/value/utils/value_util.mli | 7 +------ 7 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/plugins/value/engine/compute_functions.ml b/src/plugins/value/engine/compute_functions.ml index 50b0d1084fd..ece699c60df 100644 --- a/src/plugins/value/engine/compute_functions.ml +++ b/src/plugins/value/engine/compute_functions.ml @@ -331,7 +331,9 @@ module Make (Abstract: Abstractions.Eva) = struct try Value_util.push_call_stack kf Kglobal; store_initial_state kf init_state; - let call = { kf; arguments = []; rest = []; return = None; } in + let call = + { kf; callstack = []; arguments = []; rest = []; return = None; } + in let final_result = compute_using_spec_or_body Kglobal call None init_state in diff --git a/src/plugins/value/engine/recursion.ml b/src/plugins/value/engine/recursion.ml index 634204a9452..a5abcb4b90e 100644 --- a/src/plugins/value/engine/recursion.ml +++ b/src/plugins/value/engine/recursion.ml @@ -167,8 +167,8 @@ let make_recursion call depth = { depth; substitution; base_substitution; withdrawal; base_withdrawal; } let make call = - let call_stack = Value_util.call_stack () in - let previous_calls = List.filter (fun (f, _) -> f == call.kf) call_stack in + let is_same_kf (f, _) = Kernel_function.equal f call.kf in + let previous_calls = List.filter is_same_kf call.callstack in let depth = List.length previous_calls in if depth > 0 then Some (make_recursion call depth) diff --git a/src/plugins/value/engine/transfer_stmt.ml b/src/plugins/value/engine/transfer_stmt.ml index 68c94c2fa24..7ba3de0d199 100644 --- a/src/plugins/value/engine/transfer_stmt.ml +++ b/src/plugins/value/engine/transfer_stmt.ml @@ -538,6 +538,7 @@ module Make (Abstract: Abstractions.Eva) = struct (* Create an Eval.call *) let create_call kf args = let return = Library_functions.get_retres_vi kf in + let callstack = Value_util.call_stack () in let arguments, rest = let formals = Kernel_function.get_formals kf in let rec format_arguments acc args formals = match args, formals with @@ -551,7 +552,7 @@ module Make (Abstract: Abstractions.Eva) = struct let arguments = List.rev arguments in arguments, rest in - {kf; arguments; rest; return; } + {kf; callstack; arguments; rest; return; } let replace_value visitor substitution = function | Assign value -> Assign (Value.replace_base substitution value) diff --git a/src/plugins/value/eval.ml b/src/plugins/value/eval.ml index 74eb7635382..7a12a168d66 100644 --- a/src/plugins/value/eval.ml +++ b/src/plugins/value/eval.ml @@ -240,8 +240,13 @@ type ('loc, 'value) argument = { avalue: ('loc, 'value) assigned; } + +type call_site = kernel_function * kinstr +type callstack = call_site list + type ('loc, 'value) call = { kf: kernel_function; + callstack: callstack; arguments: ('loc, 'value) argument list; rest: (exp * ('loc, 'value) assigned) list; return: varinfo option; diff --git a/src/plugins/value/eval.mli b/src/plugins/value/eval.mli index c68cebbd998..5714172358f 100644 --- a/src/plugins/value/eval.mli +++ b/src/plugins/value/eval.mli @@ -222,9 +222,22 @@ type ('loc, 'value) argument = { avalue: ('loc, 'value) assigned; (** The value of the concrete argument. *) } +(** A call_stack is a list, telling which function was called at which + site. The head of the list tells about the latest call. *) + +(** A call site: the function called, and the call statement + (or [Kglobal] for the main function. *) +type call_site = kernel_function * kinstr + +(* A call stack is a list of call sites. The head is the latest call. + The last element is the main function. *) +type callstack = call_site list + (** A function call. *) type ('loc, 'value) call = { kf: kernel_function; (** The called function. *) + callstack: callstack; (** The current callstack + (without this call). *) arguments: ('loc, 'value) argument list; (** The arguments of the call. *) rest: (exp * ('loc, 'value) assigned) list; (** Extra-arguments. *) return: varinfo option; (** Fake varinfo to store the diff --git a/src/plugins/value/utils/value_util.ml b/src/plugins/value/utils/value_util.ml index 00f2871518e..13a005dd2af 100644 --- a/src/plugins/value/utils/value_util.ml +++ b/src/plugins/value/utils/value_util.ml @@ -24,11 +24,7 @@ open Cil_types (* Callstacks related types and functions *) -(* Function called, and calling instruction. *) -type call_site = (kernel_function * kinstr) -type callstack = call_site list - -let call_stack : callstack ref = ref [] +let call_stack : Value_types.callstack ref = ref [] (* let call_stack_for_callbacks : (kernel_function * kinstr) list ref = ref [] *) let clear_call_stack () = diff --git a/src/plugins/value/utils/value_util.mli b/src/plugins/value/utils/value_util.mli index 61df6ce5331..0bfe89cbe91 100644 --- a/src/plugins/value/utils/value_util.mli +++ b/src/plugins/value/utils/value_util.mli @@ -24,11 +24,6 @@ open Cil_types (** {2 Callstacks related types and functions} *) -(** A call_stack is a list, telling which function was called at which - site. The head of the list tells about the latest call. *) -type call_site = (kernel_function * kinstr) -type callstack = call_site list - (** Functions dealing with call stacks. *) val clear_call_stack : unit -> unit val pop_call_stack : unit -> unit @@ -36,7 +31,7 @@ val push_call_stack : kernel_function -> kinstr -> unit (** The current function is the one on top of the call stack. *) val current_kf : unit -> kernel_function -val call_stack : unit -> callstack +val call_stack : unit -> Value_types.callstack (** Prints the current callstack. *) val pp_callstack : Format.formatter -> unit -- GitLab