Skip to content

Commit c8431cd

Browse files
authored
Merge pull request #549 from goblint/issue-544-2-td3
Collect constraint unknown sets in global invariant, use them for TD3 incremental load
2 parents 792457e + 50ae696 commit c8431cd

File tree

20 files changed

+350
-75
lines changed

20 files changed

+350
-75
lines changed

g2html

gobview

src/analyses/accessAnalysis.ml

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,36 @@ struct
1717
module D = Lattice.Unit
1818
module C = Lattice.Unit
1919

20+
(* Two global invariants:
21+
1. (lval, type) -> accesses -- used for warnings
22+
2. varinfo -> set of (lval, type) -- used for IterSysVars Global *)
23+
24+
module V0 = Printable.Prod (Access.LVOpt) (Access.T)
25+
module V =
26+
struct
27+
include Printable.Either (V0) (CilType.Varinfo)
28+
let access x = `Left x
29+
let vars x = `Right x
30+
end
31+
32+
module V0Set = SetDomain.Make (V0)
2033
module G =
2134
struct
22-
include Access.AS
35+
include Lattice.Lift2 (Access.AS) (V0Set) (Printable.DefaultNames)
36+
37+
let access = function
38+
| `Bot -> Access.AS.bot ()
39+
| `Lifted1 x -> x
40+
| _ -> failwith "Access.access"
41+
let vars = function
42+
| `Bot -> V0Set.bot ()
43+
| `Lifted2 x -> x
44+
| _ -> failwith "Access.vars"
45+
let create_access access = `Lifted1 access
46+
let create_vars vars = `Lifted2 vars
2347

2448
let leq x y = !GU.postsolving || leq x y (* HACK: to pass verify*)
2549
end
26-
module V = Printable.Prod (Access.LVOpt) (Access.T)
2750

2851
let safe = ref 0
2952
let vulnerable = ref 0
@@ -34,14 +57,28 @@ struct
3457
vulnerable := 0;
3558
unsafe := 0
3659

60+
let side_vars ctx lv_opt ty =
61+
match lv_opt with
62+
| Some (v, _) ->
63+
let d =
64+
if !GU.should_warn then
65+
G.create_vars (V0Set.singleton (lv_opt, ty))
66+
else
67+
G.bot () (* HACK: just to pass validation with MCP DomVariantLattice *)
68+
in
69+
ctx.sideg (V.vars v) d;
70+
| None ->
71+
()
72+
3773
let side_access ctx ty lv_opt (conf, w, loc, e, a) =
3874
let d =
3975
if !GU.should_warn then
40-
Access.AS.singleton (conf, w, loc, e, a)
76+
G.create_access (Access.AS.singleton (conf, w, loc, e, a))
4177
else
4278
G.bot () (* HACK: just to pass validation with MCP DomVariantLattice *)
4379
in
44-
ctx.sideg (lv_opt, ty) d
80+
ctx.sideg (V.access (lv_opt, ty)) d;
81+
side_vars ctx lv_opt ty
4582

4683
let do_access (ctx: (D.t, G.t, C.t, V.t) ctx) (w:bool) (reach:bool) (conf:int) (e:exp) =
4784
let open Queries in
@@ -204,9 +241,18 @@ struct
204241
match q with
205242
| WarnGlobal g ->
206243
let g: V.t = Obj.obj g in
207-
(* ignore (Pretty.printf "WarnGlobal %a\n" CilType.Varinfo.pretty g); *)
208-
let accs = ctx.global g in
209-
Stats.time "access" (Access.warn_global safe vulnerable unsafe g) accs
244+
begin match g with
245+
| `Left g' -> (* accesses *)
246+
(* ignore (Pretty.printf "WarnGlobal %a\n" CilType.Varinfo.pretty g); *)
247+
let accs = G.access (ctx.global g) in
248+
Stats.time "access" (Access.warn_global safe vulnerable unsafe g') accs
249+
| `Right _ -> (* vars *)
250+
()
251+
end
252+
| IterSysVars (Global g, vf) ->
253+
V0Set.iter (fun v ->
254+
vf (Obj.repr (V.access v))
255+
) (G.vars (ctx.global (V.vars g)))
210256
| _ -> Queries.Result.top q
211257

212258
let finalize () =

src/analyses/apron/apronAnalysis.apron.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,9 @@ struct
377377
let exp = (BinOp (Cil.Lt, exp1, exp2, TInt (IInt, []))) in
378378
let is_lt = eval_int exp in
379379
Option.default true (ID.to_bool is_lt)
380+
| Queries.IterSysVars (vq, vf) ->
381+
let vf' x = vf (Obj.repr x) in
382+
Priv.iter_sys_vars ctx.global vq vf'
380383
| _ -> Result.top q
381384

382385

src/analyses/apron/apronPriv.apron.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ module type S =
3939

4040
val thread_join: Q.ask -> (V.t -> G.t) -> Cil.exp -> apron_components_t -> apron_components_t
4141
val thread_return: Q.ask -> (V.t -> G.t) -> (V.t -> G.t -> unit) -> ThreadIdDomain.Thread.t -> apron_components_t -> apron_components_t
42+
val iter_sys_vars: (V.t -> G.t) -> VarQuery.t -> V.t VarQuery.f -> unit (** [Queries.IterSysVars] for apron. *)
4243

4344
val init: unit -> unit
4445
val finalize: unit -> unit
@@ -68,6 +69,7 @@ struct
6869

6970
let enter_multithreaded ask getg sideg st = st
7071
let threadenter ask getg st = st
72+
let iter_sys_vars getg vq vf = ()
7173

7274
let init () = ()
7375
let finalize () = ()
@@ -342,6 +344,8 @@ struct
342344
let threadenter ask getg (st: apron_components_t): apron_components_t =
343345
{apr = getg (); priv = startstate ()}
344346

347+
let iter_sys_vars getg vq vf = () (* TODO: or report singleton global for any Global query? *)
348+
345349
let finalize () = ()
346350
end
347351

@@ -1040,6 +1044,11 @@ struct
10401044
let _,lmust,l = st.priv in
10411045
{apr = AD.bot (); priv = (W.bot (),lmust,l)}
10421046

1047+
let iter_sys_vars getg vq vf =
1048+
match vq with
1049+
| VarQuery.Global g -> vf (V.global g)
1050+
| _ -> ()
1051+
10431052
let finalize () = finalize ()
10441053
end
10451054

src/analyses/base.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ struct
3838
module D = Dom
3939
module C = Dom
4040

41+
(* Two global invariants:
42+
1. Priv.V -> Priv.G -- used for Priv
43+
2. thread -> VD -- used for thread returns *)
44+
4145
module V =
4246
struct
4347
include Printable.Either (Priv.V) (ThreadIdDomain.Thread)
@@ -1079,6 +1083,9 @@ struct
10791083
| _ -> true
10801084
end
10811085
| Q.IsMultiple v -> WeakUpdates.mem v ctx.local.weak
1086+
| Q.IterSysVars (vq, vf) ->
1087+
let vf' x = vf (Obj.repr (V.priv x)) in
1088+
Priv.iter_sys_vars (priv_getg ctx.global) vq vf'
10821089
| _ -> Q.Result.top q
10831090

10841091
let update_variable variable typ value cpa =

src/analyses/basePriv.ml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ sig
3535
val escape: Q.ask -> (V.t -> G.t) -> (V.t -> G.t -> unit) -> BaseComponents (D).t -> EscapeDomain.EscapedVars.t -> BaseComponents (D).t
3636
val enter_multithreaded: Q.ask -> (V.t -> G.t) -> (V.t -> G.t -> unit) -> BaseComponents (D).t -> BaseComponents (D).t
3737
val threadenter: Q.ask -> BaseComponents (D).t -> BaseComponents (D).t
38+
val iter_sys_vars: (V.t -> G.t) -> VarQuery.t -> V.t VarQuery.f -> unit
3839

3940
val init: unit -> unit
4041
val finalize: unit -> unit
@@ -59,6 +60,7 @@ module OldPrivBase =
5960
struct
6061
include NoFinalize
6162
module D = Lattice.Unit
63+
module V = VarinfoV
6264

6365
let startstate () = ()
6466

@@ -76,14 +78,18 @@ struct
7678
true
7779
| _ ->
7880
!GU.earlyglobs && not (ThreadFlag.is_multi ask)
81+
82+
let iter_sys_vars getg vq vf =
83+
match vq with
84+
| VarQuery.Global g -> vf g
85+
| _ -> ()
7986
end
8087

8188
(* Copy of ProtectionBasedOldPriv with is_private constantly false. *)
8289
module NonePriv: S =
8390
struct
8491
include OldPrivBase
8592
module G = BaseDomain.VD
86-
module V = VarinfoV
8793

8894
let init () = ()
8995

@@ -135,7 +141,6 @@ struct
135141
include OldPrivBase
136142

137143
module G = BaseDomain.VD
138-
module V = VarinfoV
139144

140145
let init () =
141146
if get_string "ana.osek.oil" = "" then ConfCheck.RequireMutexActivatedInit.init ()
@@ -408,7 +413,6 @@ struct
408413

409414
module D = MustVars
410415
module G = BaseDomain.VD
411-
module V = VarinfoV
412416

413417
let init () =
414418
if get_string "ana.osek.oil" = "" then ConfCheck.RequireMutexActivatedInit.init ()
@@ -599,6 +603,13 @@ struct
599603
) st.cpa st
600604

601605
let threadenter = startstate_threadenter startstate
606+
607+
let iter_sys_vars getg vq vf =
608+
match vq with
609+
| VarQuery.Global g ->
610+
vf (V.unprotected g);
611+
vf (V.protected g);
612+
| _ -> ()
602613
end
603614

604615
module AbstractLockCenteredGBase (WeakRange: Lattice.S) (SyncRange: Lattice.S) =
@@ -1351,6 +1362,7 @@ struct
13511362
let escape ask getg sideg st escaped = time "escape" (Priv.escape ask getg sideg st) escaped
13521363
let enter_multithreaded ask getg sideg st = time "enter_multithreaded" (Priv.enter_multithreaded ask getg sideg) st
13531364
let threadenter ask st = time "threadenter" (Priv.threadenter ask) st
1365+
let iter_sys_vars getg vq vf = time "iter_sys_vars" (Priv.iter_sys_vars getg vq) vf
13541366

13551367
let init () = time "init" (Priv.init) ()
13561368
let finalize () = time "finalize" (Priv.finalize) ()

src/analyses/basePriv.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ sig
2121
val escape: Queries.ask -> (V.t -> G.t) -> (V.t -> G.t -> unit) -> BaseDomain.BaseComponents (D).t -> EscapeDomain.EscapedVars.t -> BaseDomain.BaseComponents (D).t
2222
val enter_multithreaded: Queries.ask -> (V.t -> G.t) -> (V.t -> G.t -> unit) -> BaseDomain.BaseComponents (D).t -> BaseDomain.BaseComponents (D).t
2323
val threadenter: Queries.ask -> BaseDomain.BaseComponents (D).t -> BaseDomain.BaseComponents (D).t
24+
val iter_sys_vars: (V.t -> G.t) -> VarQuery.t -> V.t VarQuery.f -> unit (** [Queries.IterSysVars] for base. *)
2425

2526
val init: unit -> unit
2627
val finalize: unit -> unit

src/analyses/commonPriv.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ struct
8989
let mutex_inits: t = `Left (`Right ())
9090
let global x: t = `Right x
9191
end
92+
93+
let iter_sys_vars getg vq vf =
94+
match vq with
95+
| VarQuery.Global g -> vf (V.global g)
96+
| _ -> ()
9297
end
9398

9499
module MayVars =

src/analyses/mCP.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,13 @@ struct
361361
f ~q:(WarnGlobal (Obj.repr g)) (Result.top ()) (n, spec n, assoc n ctx.local)
362362
| Queries.PartAccess {exp; var_opt; write} ->
363363
Obj.repr (access ctx exp var_opt write)
364+
| Queries.IterSysVars (vq, fi) ->
365+
(* IterSysVars is special: argument function is lifted for each analysis *)
366+
iter (fun ((n,(module S:MCPSpec),d) as t) ->
367+
let fi' x = fi (Obj.repr (v_of n x)) in
368+
let q' = Queries.IterSysVars (vq, fi') in
369+
f ~q:q' () t
370+
) @@ spec_list ctx.local
364371
(* | EvalInt e ->
365372
(* TODO: only query others that actually respond to EvalInt *)
366373
(* 2x speed difference on SV-COMP nla-digbench-scaling/ps6-ll_valuebound5.c *)

0 commit comments

Comments
 (0)