diff --git a/src/plugins/e-acsl/tests/bts/oracle/issue-eacsl-145.res.oracle b/src/plugins/e-acsl/tests/bts/oracle/issue-eacsl-145.res.oracle index 6136cebc45ed92fb5908b315bfd4e1c9ac6d7b2c..8d646242f63b276a80e5b1aecbe4798c58561b3d 100644 --- a/src/plugins/e-acsl/tests/bts/oracle/issue-eacsl-145.res.oracle +++ b/src/plugins/e-acsl/tests/bts/oracle/issue-eacsl-145.res.oracle @@ -26,8 +26,8 @@ [eva] ====== VALUES COMPUTED ====== [eva:summary] ====== ANALYSIS SUMMARY ====== ---------------------------------------------------------------------------- - 5 functions analyzed (out of 5): 100% coverage. - In these functions, 27 statements reached (out of 27): 100% coverage. + 3 functions analyzed (out of 5): 60% coverage. + In these functions, 23 statements reached (out of 23): 100% coverage. ---------------------------------------------------------------------------- No errors or warnings raised during the analysis. ---------------------------------------------------------------------------- diff --git a/src/plugins/server/kernel_ast.ml b/src/plugins/server/kernel_ast.ml index 7ce9dd03cc6ed5e4235edfdc1d544b0471ae871b..d130f00bdd88864d88d5c8d2e04a0efd66d398e8 100644 --- a/src/plugins/server/kernel_ast.ml +++ b/src/plugins/server/kernel_ast.ml @@ -375,6 +375,19 @@ struct with Not_found -> Data.failure "Undefined function '%s'" key end +module Fundec = +struct + type t = fundec + let jtype = Pkg.Jkey "fundec" + let to_json fundec = + `String fundec.svar.vname + let of_json js = + let key = Js.to_string js in + try Kernel_function.get_definition (Globals.Functions.find_by_name key) + with Not_found | Kernel_function.No_Definition -> + Data.failure "Undefined function definition '%s'" key +end + module KfMarker = struct type record let record : record Record.signature = Record.signature () diff --git a/src/plugins/server/kernel_ast.mli b/src/plugins/server/kernel_ast.mli index d85697dec6786bf566dabe44780959aa27ab7572..e0cc3e7007dc8c3d38cfca3c0c23c4c01ee23279 100644 --- a/src/plugins/server/kernel_ast.mli +++ b/src/plugins/server/kernel_ast.mli @@ -30,6 +30,7 @@ open Cil_types module Position : Data.S with type t = Filepath.position module Kf : Data.S with type t = kernel_function +module Fundec : Data.S with type t = fundec module Ki : Data.S with type t = kinstr module Stmt : Data.S with type t = stmt module Lval : Data.S with type t = kinstr * lval diff --git a/src/plugins/value/api/general_requests.ml b/src/plugins/value/api/general_requests.ml index 2a225d40834aae737916ec85e2f06858125bd80c..1b226d8e8d271a6d3b5a718d3b81e5c33d6c96e8 100644 --- a/src/plugins/value/api/general_requests.ml +++ b/src/plugins/value/api/general_requests.ml @@ -428,9 +428,9 @@ let _array = ~name:"functionStats" ~descr:(Markdown.plain "Statistics about the last Eva analysis for each function") - ~key:(fun (kf,_stats) -> Kernel_function.get_name kf) - ~keyType:Kernel_ast.Kf.jtype - ~iter:(fun f -> FunctionStats.iter (fun kf s -> f (kf,s))) + ~key:(fun (fundec,_stats) -> fundec.svar.vname) + ~keyType:Kernel_ast.Fundec.jtype + ~iter:(fun f -> FunctionStats.iter (fun fundec s -> f (fundec,s))) ~add_update_hook:FunctionStats.register_hook model diff --git a/src/plugins/value/engine/compute_functions.ml b/src/plugins/value/engine/compute_functions.ml index a382c2266d95978e4ae10ad0414d9d057742e755..5d0cf41b0baab78657e85110dd86b5c3bd2cae33 100644 --- a/src/plugins/value/engine/compute_functions.ml +++ b/src/plugins/value/engine/compute_functions.ml @@ -201,10 +201,10 @@ module Make (Abstract: Abstractions.Eva) = struct Library_functions.warn_unsupported_spec vi.vorig_name; Spec.compute_using_specification ~warn:true call_kinstr call spec state, Eval.Cacheable - | `Def _fundec -> + | `Def fundec -> Db.Value.Call_Type_Value_Callbacks.apply (`Def, cvalue_state, call_stack); let result = Computer.compute kf call_kinstr state in - Summary.FunctionStats.recompute kf; + Summary.FunctionStats.recompute fundec; result in if pp then diff --git a/src/plugins/value/utils/summary.ml b/src/plugins/value/utils/summary.ml index b9f8b34078bb6422b3c976dd167135b1ca211ca5..1429c0262b314bff082b941cf0e2fe9d495a1245 100644 --- a/src/plugins/value/utils/summary.ml +++ b/src/plugins/value/utils/summary.ml @@ -157,11 +157,12 @@ let get_status ip = in Property_status.fold_on_statuses aux_status ip None -let compute_fun_stats kf = +let compute_fun_stats fundec = let alarms = AlarmsStats.create 13 and coverage = Coverage.make () and statuses = Statuses.make () in + let kf = Globals.Functions.get fundec.Cil_types.svar in let do_status alarm ip = match get_status ip with | None -> () @@ -183,11 +184,7 @@ let compute_fun_stats kf = Coverage.incr coverage ~reachable; Annotations.iter_code_annot (do_annot stmt) stmt in - begin match kf.Cil_types.fundec with - | Declaration _ -> () - | Definition (fundec,_loc) -> - List.iter do_stmt fundec.Cil_types.sallstmts - end; + List.iter do_stmt fundec.Cil_types.sallstmts; { fun_coverage = coverage; fun_alarm_count = AlarmsStats.to_list alarms; fun_alarm_statuses = statuses; } @@ -196,7 +193,7 @@ let compute_fun_stats kf = module FunctionStats_Type = Datatype.Make (struct include Datatype.Serializable_undefined type t = fun_stats - let name = "Eva.Value_results.FunctionStats_Type" + let name = "Eva.Summary.FunctionStats_Type" let reprs = [{ fun_coverage = Coverage.make (); fun_alarm_count = []; @@ -205,23 +202,26 @@ module FunctionStats_Type = Datatype.Make (struct end) module FunctionStats = struct - include Kernel_function.Make_Table + include State_builder.Hashtbl + (Cil_datatype.Fundec.Hashtbl) (FunctionStats_Type) (struct - let name = "Eva.Value_results.FunctionStats" + let name = "Eva.Summary.FunctionStats" let dependencies = [ Db.Value.self ] let size = 17 end) module Hook = Hook.Build (struct - type t = Cil_types.kernel_function * fun_stats + type t = Cil_types.fundec * fun_stats end) let compute kf = let stats = compute_fun_stats kf in Hook.apply (kf,stats); stats - let get = memo compute + let get kf = + try Some (find kf) + with Not_found -> None let recompute kf = replace kf (compute kf) let register_hook = Hook.extend end @@ -289,19 +289,20 @@ let compute_stats () = and prog_stmt_coverage = Coverage.make () and prog_alarms = AlarmsStats.create 131 in - let do_fun kf = - let reachable = Value_results.is_called kf in - let consider = consider_function (Kernel_function.get_vi kf) in - if consider then - Coverage.incr prog_fun_coverage ~reachable; - if reachable then begin - let fun_stats = FunctionStats.get kf in + let do_fun fundec = + let consider = consider_function fundec.Cil_types.svar in + match FunctionStats.get fundec with + | Some fun_stats -> AlarmsStats.add_list prog_alarms fun_stats.fun_alarm_count; if consider then - Coverage.add prog_stmt_coverage fun_stats.fun_coverage; - end + begin + Coverage.incr prog_fun_coverage ~reachable:true; + Coverage.add prog_stmt_coverage fun_stats.fun_coverage; + end + | None -> + if consider then Coverage.incr prog_fun_coverage ~reachable:false; in - Globals.Functions.iter do_fun; + Globals.Functions.iter_on_fundecs do_fun; let alarms_statuses, assertions_statuses, preconds_statuses = compute_statuses () and eva_events, kernel_events = compute_events () in diff --git a/src/plugins/value/utils/summary.mli b/src/plugins/value/utils/summary.mli index 9bfbc90e4c66eafe5d382c5ed107ba5672f83fcf..a0e912834d72d655bd40c7b91dd9cca6a8b763cf 100644 --- a/src/plugins/value/utils/summary.mli +++ b/src/plugins/value/utils/summary.mli @@ -66,16 +66,16 @@ type program_stats = module FunctionStats : sig (** Get the current analysis statistics for a function *) - val get: Cil_types.kernel_function -> fun_stats + val get: Cil_types.fundec -> fun_stats option - (** Iterate on every function statistices *) - val iter: (Cil_types.kernel_function -> fun_stats -> unit) -> unit + (** Iterate on every function statistics *) + val iter: (Cil_types.fundec -> fun_stats -> unit) -> unit (** Trigger the recomputation of function stats *) - val recompute: Cil_types.kernel_function -> unit + val recompute: Cil_types.fundec -> unit (** Set a hook on function statistics computation *) - val register_hook: (Cil_types.kernel_function * fun_stats -> unit) -> unit + val register_hook: (Cil_types.fundec * fun_stats -> unit) -> unit end (** Compute analysis statistics. *) diff --git a/tests/spec/oracle/generalized_check.0.res.oracle b/tests/spec/oracle/generalized_check.0.res.oracle index f93e7228b403b708b01b4386186ab29d200d1a5a..4fc947aed52f0310962541382bab507065ba34a8 100644 --- a/tests/spec/oracle/generalized_check.0.res.oracle +++ b/tests/spec/oracle/generalized_check.0.res.oracle @@ -30,8 +30,8 @@ __retres ∈ {0} [eva:summary] ====== ANALYSIS SUMMARY ====== ---------------------------------------------------------------------------- - 3 functions analyzed (out of 3): 100% coverage. - In these functions, 25 statements reached (out of 28): 89% coverage. + 2 functions analyzed (out of 3): 66% coverage. + In these functions, 25 statements reached (out of 25): 100% coverage. ---------------------------------------------------------------------------- Some errors and warnings have been raised during the analysis: by the Eva analyzer: 0 errors 1 warning