@@ -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
@@ -282,7 +288,7 @@ struct
282288 | _ -> false (* remove everything else (globals, global privs) *)
283289 )
284290 in
285- let unify_apr = ApronDomain.A. unify Man. mgr new_apr new_fun_apr in (* TODO: unify_with *)
291+ let unify_apr = AD. unify new_apr new_fun_apr in (* TODO: unify_with *)
286292 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;
287293 let unify_st = {fun_st with apr = unify_apr} in
288294 if AD. type_tracked (Cilfacade. fundec_return_type f) then (
@@ -354,6 +360,34 @@ struct
354360 | None -> st'
355361
356362
363+ let query_invariant ctx context =
364+ let keep_local = GobConfig. get_bool " ana.apron.invariant.local" in
365+ let keep_global = GobConfig. get_bool " ana.apron.invariant.global" in
366+
367+ let apr = ctx.local.apr in
368+ (* filter variables *)
369+ let var_filter v = match V. find_metadata v with
370+ | Some (Global _ ) -> keep_global
371+ | Some Local -> keep_local
372+ | _ -> false
373+ in
374+ let apr = AD. keep_filter apr var_filter in
375+
376+ let one_var = GobConfig. get_bool " ana.apron.invariant.one-var" in
377+ let scope = Node. find_fundec ctx.node in
378+
379+ AD. invariant ~scope apr
380+ |> List. enum
381+ |> Enum. filter_map (fun (lincons1 : Lincons1.t ) ->
382+ (* filter one-vars *)
383+ if one_var || Apron.Linexpr0. get_size lincons1.lincons0.linexpr0 > = 2 then
384+ CilOfApron. cil_exp_of_lincons1 scope lincons1
385+ |> Option. filter (fun exp -> not (InvariantCil. exp_contains_tmp exp) && InvariantCil. exp_is_in_scope scope exp)
386+ else
387+ None
388+ )
389+ |> Enum. fold (fun acc x -> Invariant. (acc && of_exp x)) Invariant. none
390+
357391 let query ctx (type a ) (q : a Queries.t ): a Queries.result =
358392 let open Queries in
359393 let st = ctx.local in
@@ -383,8 +417,7 @@ struct
383417 let is_lt = eval_int exp in
384418 Option. default true (ID. to_bool is_lt)
385419 | Queries. Invariant context ->
386- let scope = Node. find_fundec ctx.node in
387- D. invariant ~scope ctx.local
420+ query_invariant ctx context
388421 | _ -> Result. top q
389422
390423
@@ -434,8 +467,19 @@ struct
434467 let sync ctx reason =
435468 (* After the solver is finished, store the results (for later comparison) *)
436469 if ! GU. postsolving then begin
470+ let keep_local = GobConfig. get_bool " ana.apron.invariant.local" in
471+ let keep_global = GobConfig. get_bool " ana.apron.invariant.global" in
472+
473+ (* filter variables *)
474+ let var_filter v = match V. find_metadata v with
475+ | Some (Global _ ) -> keep_global
476+ | Some Local -> keep_local
477+ | _ -> false
478+ in
479+ let st = keep_filter ctx.local.apr var_filter in
480+
437481 let old_value = RH. find_default results ctx.node (AD. bot () ) in
438- let new_value = AD. join old_value ctx.local.apr in
482+ let new_value = AD. join old_value st in
439483 RH. replace results ctx.node new_value;
440484 end ;
441485 Priv. sync (Analyses. ask_of_ctx ctx) ctx.global ctx.sideg ctx.local (reason :> [`Normal | `Join | `Return | `Init | `Thread] )
@@ -446,21 +490,14 @@ struct
446490 module OctApron = ApronPrecCompareUtil. OctagonD
447491 let store_data file =
448492 let convert (m : AD.t RH.t ): OctApron.t RH.t =
449- let convert_single (a : AD.t ): OctApron.t =
450- if Oct. manager_is_oct AD.Man. mgr then
451- Oct.Abstract1. to_oct a
452- else
453- let generator = AD. to_lincons_array a in
454- OctApron. of_lincons_array generator
455- in
456- RH. map (fun _ -> convert_single) m
493+ RH. map (fun _ -> AD. to_oct) m
457494 in
458495 let post_process m =
459496 let m = Stats. time " convert" convert m in
460497 RH. map (fun _ v -> OctApron. marshal v) m
461498 in
462499 let results = post_process results in
463- let name = name () ^ " (domain: " ^ (AD.Man. name () ) ^ " , privatization: " ^ (Priv. name () ) ^ (if GobConfig. get_bool " ana.apron.threshold_widening" then " , th" else " " ) ^ " )" in
500+ let name = name () ^ " (domain: " ^ (AD. name () ) ^ " , privatization: " ^ (Priv. name () ) ^ (if GobConfig. get_bool " ana.apron.threshold_widening" then " , th" else " " ) ^ " )" in
464501 let results: ApronPrecCompareUtil. dump = {marshalled = results; name } in
465502 Serialize. marshal results file
466503
477514let spec_module: (module MCPSpec ) Lazy. t =
478515 lazy (
479516 let module Man = (val ApronDomain. get_manager () ) in
480- let module AD = ApronDomain. D2 (Man ) in
517+ let module AD = ApronDomain. D3 (Man ) in
518+ let diff_box = GobConfig. get_bool " ana.apron.invariant.diff-box" in
519+ let module AD = (val if diff_box then (module ApronDomain. BoxProd (AD ): ApronDomain. S3 ) else (module AD )) in
481520 let module Priv = (val ApronPriv. get_priv () ) in
482521 let module Spec = SpecFunctor (AD ) (Priv ) in
483522 (module Spec )
0 commit comments