diff --git a/Makefile b/Makefile index 9fa91830176abbba08cd816a115b0fbcb8279c88..75ce964f2676d2864a79bc775967653a12fb1194 100644 --- a/Makefile +++ b/Makefile @@ -856,7 +856,7 @@ endif # - try to keep the legacy Value before Eva PLUGIN_CMO:= partitioning/split_strategy domains/domain_mode value_parameters \ utils/eva_audit utils/value_perf utils/eva_annotations \ - utils/value_util utils/red_statuses \ + utils/eva_dynamic utils/value_util utils/red_statuses \ utils/mark_noresults \ utils/widen_hints_ext utils/widen \ partitioning/split_return \ diff --git a/headers/header_spec.txt b/headers/header_spec.txt index 081be10cddc9316980317342a9e9121ece630708..40c2cc32fa2392b11cce300ba61272f9c56de8ce 100644 --- a/headers/header_spec.txt +++ b/headers/header_spec.txt @@ -1483,6 +1483,8 @@ src/plugins/value/utils/eva_annotations.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/eva_annotations.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/eva_audit.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/eva_audit.mli: CEA_LGPL_OR_PROPRIETARY +src/plugins/value/utils/eva_dynamic.ml: CEA_LGPL_OR_PROPRIETARY +src/plugins/value/utils/eva_dynamic.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/structure.ml: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/structure.mli: CEA_LGPL_OR_PROPRIETARY src/plugins/value/utils/summary.ml: CEA_LGPL_OR_PROPRIETARY diff --git a/src/plugins/value/domains/cvalue/cvalue_domain.ml b/src/plugins/value/domains/cvalue/cvalue_domain.ml index 80abee069ddbf66e854c3852c71e984751c2c637..57dd8ab350c1bc6586f6a7e13e6e336afdadb003 100644 --- a/src/plugins/value/domains/cvalue/cvalue_domain.ml +++ b/src/plugins/value/domains/cvalue/cvalue_domain.ml @@ -559,7 +559,7 @@ module State = struct let display_results () = Value_parameters.result "====== VALUES COMPUTED ======"; - Callgraph.Uses.iter_in_rev_order display; + Eva_dynamic.Callgraph.iter_in_rev_order display; Value_parameters.result "%t" Value_perf.display let post_analysis _state = diff --git a/src/plugins/value/engine/compute_functions.ml b/src/plugins/value/engine/compute_functions.ml index 718da24a52985bef50b701c9ca5e90154106c37e..e294447de6682233ba5f0af253b3df0c0c345341 100644 --- a/src/plugins/value/engine/compute_functions.ml +++ b/src/plugins/value/engine/compute_functions.ml @@ -108,10 +108,10 @@ let post_analysis () = (* Try to refine the 'Unknown' statuses that have been emitted during this analysis. *) Eval_annots.mark_green_and_red (); - Eval_annots.mark_rte (); + Eva_dynamic.RteGen.mark_generated_rte (); post_analysis_cleanup ~aborted:false; (* Remove redundant alarms *) - if Value_parameters.RmAssert.get () then !Db.Value.rm_asserts () + if Value_parameters.RmAssert.get () then Eva_dynamic.Scope.rm_asserts () (* Registers signal handlers for SIGUSR1 and SIGINT to cleanly abort the Eva analysis. Returns a function that restores previous signal behaviors after diff --git a/src/plugins/value/gui_files/register_gui.ml b/src/plugins/value/gui_files/register_gui.ml index 5adf217e9f95053da29b3c13851e32527318dae4..3587497948dafbc7d40353138da1651a5b8202c2 100644 --- a/src/plugins/value/gui_files/register_gui.ml +++ b/src/plugins/value/gui_files/register_gui.ml @@ -227,9 +227,7 @@ let gui_compute_values (main_ui:main_ui) = let cleaned_outputs kf s = let outs = Db.Outputs.kinstr (Kstmt s) in - let accept = - Callgraph.Uses.accept_base ~with_formals:true ~with_locals:true kf - in + let accept = Eva_dynamic.Callgraph.accept_base kf in let filter = Locations.Zone.filter_base accept in Option.map filter outs diff --git a/src/plugins/value/legacy/eval_annots.ml b/src/plugins/value/legacy/eval_annots.ml index 7e3434b351b92234aeaef40a13bcaaabd737fbed..68aed0aadab7bc2b5171980bd0962f7b4f3e8c94 100644 --- a/src/plugins/value/legacy/eval_annots.ml +++ b/src/plugins/value/legacy/eval_annots.ml @@ -102,11 +102,6 @@ let mark_unreachable () = Annotations.iter_all_code_annot do_code_annot; Visitor.visitFramacFile unreach (Ast.get ()) -let mark_rte () = - let list = !Db.RteGen.get_all_status () in - let mark kf = List.iter (fun (_kind, set, _get) -> set kf true) list in - Globals.Functions.iter (fun kf -> if !Db.Value.is_called kf then mark kf) - let c_labels kf cs = if !Db.Value.use_spec_instead_of_definition kf then Cil_datatype.Logic_label.Map.empty diff --git a/src/plugins/value/legacy/eval_annots.mli b/src/plugins/value/legacy/eval_annots.mli index 03fbb8c51541c594f3d7954bc53a77ce0460f303..ba43b7aa2f95bfa0d3198beef927964e5c40fb74 100644 --- a/src/plugins/value/legacy/eval_annots.mli +++ b/src/plugins/value/legacy/eval_annots.mli @@ -26,5 +26,4 @@ val has_requires: spec -> bool val mark_invalid_initializers: unit -> unit val mark_unreachable: unit -> unit val mark_green_and_red: unit -> unit -val mark_rte: unit -> unit val c_labels: kernel_function -> Value_types.callstack -> Eval_terms.labels_states diff --git a/src/plugins/value/utils/eva_dynamic.ml b/src/plugins/value/utils/eva_dynamic.ml new file mode 100644 index 0000000000000000000000000000000000000000..b62a8ec73cb2f5f61f8db4a83e434ccfcbc2f15b --- /dev/null +++ b/src/plugins/value/utils/eva_dynamic.ml @@ -0,0 +1,67 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2021 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +let get ~plugin name typ ~fallback = + try Dynamic.get ~plugin name typ + with Failure _ | Dynamic.(Unbound_value _ | Incompatible_type _) -> fallback + +module Callgraph = struct + let plugin = "callgraph" + + let iter_in_rev_order f = + let fallback = Globals.Functions.iter in + let typ = Datatype.(func (func Kernel_function.ty unit) unit) in + get ~plugin "iter_in_rev_order" typ ~fallback f + + let accept_base kf v = + let fallback _ _ = true in + let typ = Datatype.(func2 Kernel_function.ty Base.ty bool) in + get ~plugin "accept_base" typ ~fallback kf v +end + +module Scope = struct + let plugin = "scope" + + let rm_asserts () = + let fallback () = + Value_parameters.warning + "The scope plugin is missing: cannot remove redundant alarms." + in + let typ = Datatype.(func unit unit) in + get ~plugin "rm_asserts" typ ~fallback () +end + +module RteGen = struct + let plugin = "RteGen" + + let all_statuses () = + let kf = Kernel_function.ty in + let typ = + Datatype.(list (triple string (func2 kf bool unit) (func kf bool))) + in + get ~plugin "all_statuses" typ ~fallback:[] + + let mark_generated_rte () = + let list = all_statuses () in + let mark kf = List.iter (fun (_kind, set, _get) -> set kf true) list in + Globals.Functions.iter (fun kf -> if !Db.Value.is_called kf then mark kf) +end diff --git a/src/plugins/value/utils/eva_dynamic.mli b/src/plugins/value/utils/eva_dynamic.mli new file mode 100644 index 0000000000000000000000000000000000000000..85648b915300cf697ce591ed119e748edad837ff --- /dev/null +++ b/src/plugins/value/utils/eva_dynamic.mli @@ -0,0 +1,43 @@ +(**************************************************************************) +(* *) +(* This file is part of Frama-C. *) +(* *) +(* Copyright (C) 2007-2021 *) +(* CEA (Commissariat à l'énergie atomique et aux énergies *) +(* alternatives) *) +(* *) +(* you can redistribute it and/or modify it under the terms of the GNU *) +(* Lesser General Public License as published by the Free Software *) +(* Foundation, version 2.1. *) +(* *) +(* It is distributed in the hope that it will be useful, *) +(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) +(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) +(* GNU Lesser General Public License for more details. *) +(* *) +(* See the GNU Lesser General Public License version 2.1 *) +(* for more details (enclosed in the file licenses/LGPLv2.1). *) +(* *) +(**************************************************************************) + +(** Access to other plugins API via {Dynamic.get}. *) + +module Callgraph: sig + (** Iterates over all functions in the callgraph in reverse order, i.e. from + callees to callers. If callgraph is missing, the order is unspecified. *) + val iter_in_rev_order: (Kernel_function.t -> unit) -> unit + + (** Returns [true] if [base] is a global, or a formal or local of either [kf] + or one of its callers. If callgraph is missing, always returns true. *) + val accept_base: Kernel_function.t -> Base.t -> bool +end + +module Scope: sig + (** Removes redundant assertions. Warns if the scope plugin is missing. *) + val rm_asserts: unit -> unit +end + +module RteGen: sig + (** Marks all RTE as generated. Does nothing if the rte plugin is missing. *) + val mark_generated_rte: unit -> unit +end