@@ -6,12 +6,18 @@ open ApronDomain
66
77module M = Messages
88
9- module SpecFunctor (AD : ApronDomain.S2 ) (Priv : ApronPriv.S ) : Analyses. MCPSpec =
9+ module SpecFunctor (AD : ApronDomain.S3 ) (Priv : ApronPriv.S ) : Analyses. MCPSpec =
1010struct
1111 include Analyses. DefaultSpec
1212
1313 let name () = " apron"
1414
15+ module AD =
16+ struct
17+ include AD
18+ include ApronDomain. Tracked
19+ end
20+
1521 module Priv = Priv (AD )
1622 module D = ApronComponents (AD ) (Priv. D )
1723 module G = Priv. G
@@ -334,7 +340,7 @@ struct
334340 | _ -> false (* remove everything else (globals, global privs, reachable things from the caller) *)
335341 )
336342 in
337- let unify_apr = ApronDomain.A. unify Man. mgr new_apr new_fun_apr in (* TODO: unify_with *)
343+ let unify_apr = AD. unify new_apr new_fun_apr in (* TODO: unify_with *)
338344 if M. tracing then M. tracel " combine" " apron unifying %a %a = %a\n " AD. pretty new_apr AD. pretty new_fun_apr AD. pretty unify_apr;
339345 let unify_st = {fun_st with apr = unify_apr} in
340346 if AD. type_tracked (Cilfacade. fundec_return_type f) then (
@@ -443,6 +449,34 @@ struct
443449 | None -> st'
444450
445451
452+ let query_invariant ctx context =
453+ let keep_local = GobConfig. get_bool " ana.apron.invariant.local" in
454+ let keep_global = GobConfig. get_bool " ana.apron.invariant.global" in
455+
456+ let apr = ctx.local.apr in
457+ (* filter variables *)
458+ let var_filter v = match V. find_metadata v with
459+ | Some (Global _ ) -> keep_global
460+ | Some Local -> keep_local
461+ | _ -> false
462+ in
463+ let apr = AD. keep_filter apr var_filter in
464+
465+ let one_var = GobConfig. get_bool " ana.apron.invariant.one-var" in
466+ let scope = Node. find_fundec ctx.node in
467+
468+ AD. invariant ~scope apr
469+ |> List. enum
470+ |> Enum. filter_map (fun (lincons1 : Lincons1.t ) ->
471+ (* filter one-vars *)
472+ if one_var || Apron.Linexpr0. get_size lincons1.lincons0.linexpr0 > = 2 then
473+ CilOfApron. cil_exp_of_lincons1 scope lincons1
474+ |> Option. filter (fun exp -> not (InvariantCil. exp_contains_tmp exp) && InvariantCil. exp_is_in_scope scope exp)
475+ else
476+ None
477+ )
478+ |> Enum. fold (fun acc x -> Invariant. (acc && of_exp x)) Invariant. none
479+
446480 let query ctx (type a ) (q : a Queries.t ): a Queries.result =
447481 let open Queries in
448482 let st = ctx.local in
@@ -472,6 +506,8 @@ struct
472506 let exp = (BinOp (Cil. Lt , exp1, exp2, TInt (IInt , [] ))) in
473507 let is_lt = eval_int exp in
474508 Option. default true (ID. to_bool is_lt)
509+ | Queries. Invariant context ->
510+ query_invariant ctx context
475511 | _ -> Result. top q
476512
477513
@@ -523,8 +559,19 @@ struct
523559 let sync ctx reason =
524560 (* After the solver is finished, store the results (for later comparison) *)
525561 if ! GU. postsolving then begin
562+ let keep_local = GobConfig. get_bool " ana.apron.invariant.local" in
563+ let keep_global = GobConfig. get_bool " ana.apron.invariant.global" in
564+
565+ (* filter variables *)
566+ let var_filter v = match V. find_metadata v with
567+ | Some (Global _ ) -> keep_global
568+ | Some Local -> keep_local
569+ | _ -> false
570+ in
571+ let st = keep_filter ctx.local.apr var_filter in
572+
526573 let old_value = RH. find_default results ctx.node (AD. bot () ) in
527- let new_value = AD. join old_value ctx.local.apr in
574+ let new_value = AD. join old_value st in
528575 RH. replace results ctx.node new_value;
529576 end ;
530577 Priv. sync (Analyses. ask_of_ctx ctx) ctx.global ctx.sideg ctx.local (reason :> [`Normal | `Join | `Return | `Init | `Thread] )
@@ -535,21 +582,14 @@ struct
535582 module OctApron = ApronPrecCompareUtil. OctagonD
536583 let store_data file =
537584 let convert (m : AD.t RH.t ): OctApron.t RH.t =
538- let convert_single (a : AD.t ): OctApron.t =
539- if Oct. manager_is_oct AD.Man. mgr then
540- Oct.Abstract1. to_oct a
541- else
542- let generator = AD. to_lincons_array a in
543- OctApron. of_lincons_array generator
544- in
545- RH. map (fun _ -> convert_single) m
585+ RH. map (fun _ -> AD. to_oct) m
546586 in
547587 let post_process m =
548588 let m = Stats. time " convert" convert m in
549589 RH. map (fun _ v -> OctApron. marshal v) m
550590 in
551591 let results = post_process results in
552- let name = name () ^ " (domain: " ^ (AD.Man. name () ) ^ " , privatization: " ^ (Priv. name () ) ^ (if GobConfig. get_bool " ana.apron.threshold_widening" then " , th" else " " ) ^ " )" in
592+ let name = name () ^ " (domain: " ^ (AD. name () ) ^ " , privatization: " ^ (Priv. name () ) ^ (if GobConfig. get_bool " ana.apron.threshold_widening" then " , th" else " " ) ^ " )" in
553593 let results: ApronPrecCompareUtil. dump = {marshalled = results; name } in
554594 Serialize. marshal results file
555595
566606let spec_module: (module MCPSpec ) Lazy. t =
567607 lazy (
568608 let module Man = (val ApronDomain. get_manager () ) in
569- let module AD = ApronDomain. D2 (Man ) in
609+ let module AD = ApronDomain. D3 (Man ) in
610+ let diff_box = GobConfig. get_bool " ana.apron.invariant.diff-box" in
611+ let module AD = (val if diff_box then (module ApronDomain. BoxProd (AD ): ApronDomain. S3 ) else (module AD )) in
570612 let module Priv = (val ApronPriv. get_priv () ) in
571613 let module Spec = SpecFunctor (AD ) (Priv ) in
572614 (module Spec )
0 commit comments