From 64c8febbee372a576383a23daf0206bc7b346b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Mon, 8 Feb 2021 19:13:39 +0100 Subject: [PATCH] [wp] (some) smoke fixes --- src/plugins/wp/cfgAnnot.ml | 26 +++++++++++++++++--------- src/plugins/wp/cfgAnnot.mli | 13 ++++++++----- src/plugins/wp/cfgCalculus.ml | 14 +++++++++++--- src/plugins/wp/cfgInfos.ml | 15 ++++++++++----- src/plugins/wp/wpAnnot.mli | 1 + 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/plugins/wp/cfgAnnot.ml b/src/plugins/wp/cfgAnnot.ml index 3ed9641b471..454dba14289 100644 --- a/src/plugins/wp/cfgAnnot.ml +++ b/src/plugins/wp/cfgAnnot.ml @@ -126,13 +126,12 @@ let get_behavior kf let p_asgn, e_asgn = normalize_assigns kf ki exits bhv ~active bhv.b_assigns in let smokes = - if smoking then - if bhv.b_assumes = [] && bhv.b_requires = [] then [] else - let bname = - if Cil.is_default_behavior bhv then "default" else bhv.b_name in - let id = bname ^ "_requires" in - let doomed = Property.ip_requires_of_behavior kf Kglobal bhv in - [smoke kf ~id ~doomed ()] + if smoking && bhv.b_requires <> [] then + let bname = + if Cil.is_default_behavior bhv then "default" else bhv.b_name in + let id = bname ^ "_requires" in + let doomed = Property.ip_requires_of_behavior kf Kglobal bhv in + [smoke kf ~id ~doomed ()] else [] in { @@ -320,7 +319,7 @@ let get_code_assertions ?smoking kf stmt = | None -> ca | Some r -> if WpReached.smoking r stmt then - let s = smoke kf ~id:"deadcode" ~unreachable:stmt () in + let s = smoke kf ~id:"dead_code" ~unreachable:stmt () in { ca with code_verified = s :: ca.code_verified } else ca @@ -333,6 +332,8 @@ type loop_contract = { loop_established: WpPropId.pred_info list; (* to be assumed for loop current *) loop_invariants: WpPropId.pred_info list; + (* to be proved after loop invariants *) + loop_smoke: WpPropId.pred_info list; (* to be verified after loop body *) loop_preserved: WpPropId.pred_info list; (* assigned by loop body *) @@ -344,6 +345,7 @@ let reverse_loop_contract l = { loop_invariants = List.rev l.loop_invariants ; loop_preserved = List.rev l.loop_preserved ; loop_assigns = List.rev l.loop_assigns ; + loop_smoke = List.rev l.loop_smoke ; } let default_assigns stmt l = @@ -403,11 +405,17 @@ module LoopContract = WpContext.StaticGenerator(CodeKey) loop_established = [] ; loop_invariants = [] ; loop_preserved = [] ; + loop_smoke = [] ; loop_assigns = [] ; } end) -let get_loop_contract kf stmt = LoopContract.get (kf,stmt) +let get_loop_contract ?(smoking=false) kf stmt = + let lc = LoopContract.get (kf,stmt) in + if smoking && not (WpReached.is_dead_code stmt) then + let g = smoke kf ~id:"dead_loop" ~unreachable:stmt () in + { lc with loop_smoke = g :: lc.loop_smoke } + else lc (* -------------------------------------------------------------------------- *) (* --- Clear Tablesnts --- *) diff --git a/src/plugins/wp/cfgAnnot.mli b/src/plugins/wp/cfgAnnot.mli index 9ba615b4305..a2f997986a8 100644 --- a/src/plugins/wp/cfgAnnot.mli +++ b/src/plugins/wp/cfgAnnot.mli @@ -72,16 +72,19 @@ val get_code_assertions : type loop_contract = { (** to be verified at loop entry *) - loop_established: pred_info list; + loop_established: WpPropId.pred_info list; (** to be assumed for loop current *) - loop_invariants: pred_info list; + loop_invariants: WpPropId.pred_info list; + (** to be proved after loop invariants *) + loop_smoke: WpPropId.pred_info list; (** to be verified after loop body *) - loop_preserved: pred_info list; + loop_preserved: WpPropId.pred_info list; (** assigned by loop body *) - loop_assigns: assigns_full_info list; + loop_assigns: WpPropId.assigns_full_info list; } -val get_loop_contract : kernel_function -> stmt -> loop_contract +val get_loop_contract : ?smoking:bool -> + kernel_function -> stmt -> loop_contract (* -------------------------------------------------------------------------- *) (* --- Property Accessors : Call Contracts --- *) diff --git a/src/plugins/wp/cfgCalculus.ml b/src/plugins/wp/cfgCalculus.ml index 431b3df41f3..10e8f52ca38 100644 --- a/src/plugins/wp/cfgCalculus.ml +++ b/src/plugins/wp/cfgCalculus.ml @@ -98,10 +98,11 @@ let is_active_mode ~mode ~goal (p: Property.t) = | IPDecrease { id_ca = None } -> is_default_bhv mode | IPDecrease { id_ca = Some ca } -> is_selected_ca mode ~goal ca | IPComplete _ | IPDisjoint _ -> is_default_bhv mode + | IPOther _ -> true | IPFrom _ | IPGlobalInvariant _ | IPTypeInvariant _ -> (*TODO: is it in pass or not ? *) assert false | IPAxiomatic _ | IPAxiom _ | IPLemma _ - | IPOther _ | IPExtended _ | IPBehavior _ + | IPExtended _ | IPBehavior _ | IPReachable _ | IPPropertyInstance _ -> assert false (* n/a *) @@ -220,7 +221,13 @@ struct W.switch env.we s value (List.map (fun (e,v) -> [e], wp env v) cases) (wp env default) - | Loop _ -> loop env a s (CfgAnnot.get_loop_contract env.mode.kf s) + | Loop _ -> + let m = env.mode in + let smoking = + is_default_bhv m && + WpLog.SmokeTests.get () && + WpLog.SmokeDeadloop.get () in + loop env a s (CfgAnnot.get_loop_contract ~smoking m.kf s) | Edges -> successors env a (* Compute loops *) @@ -233,6 +240,7 @@ struct List.fold_right (use_assigns env) lc.loop_assigns @@ W.label env.we None loop_current @@ List.fold_right (use_property env) lc.loop_invariants @@ + List.fold_right (prove_property env) lc.loop_smoke @@ let q = List.fold_right (prove_property env) lc.loop_preserved @@ List.fold_right (prove_assigns env) lc.loop_assigns @@ @@ -382,7 +390,7 @@ struct if body <> None && is_default_bhv mode && WpLog.SmokeTests.get () && - WpLog.SmokeDeadcall.get () + WpLog.SmokeDeadcode.get () then Some (WpReached.reachability kf) else None in let env = { mode ; props ; body ; succ ; dead ; diff --git a/src/plugins/wp/cfgInfos.ml b/src/plugins/wp/cfgInfos.ml index ac9c245b0ad..adcec5bbcc8 100644 --- a/src/plugins/wp/cfgInfos.ml +++ b/src/plugins/wp/cfgInfos.ml @@ -113,11 +113,12 @@ let selected_bhv ~bhv ~prop (b : Cil_types.funbehavior) = begin (selected_assigns ~prop b.b_assigns) || (selected_allocates ~prop b.b_allocation) || + (Wp_parameters.SmokeTests.get () && b.b_requires <> []) || (List.exists (selected_postcond ~prop) b.b_post_cond) end let selected_main_bhv ~bhv ~prop (b : Cil_types.funbehavior) = - (bhv = [] || List.mem b.b_name bhv) && (selected_requires ~prop) b + (bhv = [] || List.mem b.b_name bhv) && (selected_requires ~prop b) (* -------------------------------------------------------------------------- *) (* --- Calls --- *) @@ -225,10 +226,12 @@ let compile Key.{ kf ; bhv ; prop } = let ca = CfgAnnot.get_code_assertions kf stmt in let ca_pids = List.map fst ca.code_verified in let loop_pids = loop_contract_pids kf stmt in - if dead then begin - infos.doomed <- Bag.concat infos.doomed (Bag.list ca_pids) ; - infos.doomed <- Bag.concat infos.doomed (Bag.list loop_pids) ; - end else + if dead then + begin + infos.doomed <- Bag.concat infos.doomed (Bag.list ca_pids) ; + infos.doomed <- Bag.concat infos.doomed (Bag.list loop_pids) ; + end + else begin if not infos.annots && ( List.exists (selected ~bhv ~prop) ca_pids || @@ -239,6 +242,8 @@ let compile Key.{ kf ; bhv ; prop } = end ) cfg.stmt_table ; end body ; + (* Doomed *) + Bag.iter WpAnnot.set_unreachable infos.doomed ; (* Collected Infos *) infos diff --git a/src/plugins/wp/wpAnnot.mli b/src/plugins/wp/wpAnnot.mli index 211c0ee80a7..1faa344c267 100644 --- a/src/plugins/wp/wpAnnot.mli +++ b/src/plugins/wp/wpAnnot.mli @@ -34,6 +34,7 @@ open Cil_types val unreachable_proved : int ref val unreachable_failed : int ref +val set_unreachable : WpPropId.prop_id -> unit type asked_assigns = NoAssigns | OnlyAssigns | WithAssigns -- GitLab