1919(* * The main point of this file---generating a [FwdGlobConstrSys] from a [Spec]. *)
2020module FromSpec (S :Spec ) (Cfg :CfgForward ) (I : Increment )
2121 : sig
22- include FwdGlobConstrSys with module LVar = VarF (S. C )
22+ include FwdGlobConstrSys with module LVar = VarDigestF (S. C ) ( S. P )
2323 and module GVar = GVarFCNW (S. V )(S. C )
2424 and module D = S. D
2525 and module G = GVarL (S. G ) (S. D )
2626 end
2727=
2828struct
29- type lv = MyCFG .node * S .C .t
29+ type lv = MyCFG .node * S .C .t * S .P .t
3030 (* type gv = varinfo *)
3131 type ld = S .D .t
3232 (* type gd = S.G.t *)
33- module LVar = VarF (S .C )
33+ module LVar = VarDigestF (S .C ) ( S .P )
3434 module GVar = GVarFCNW (S .V )(S .C )
3535 module D = S .D
3636 module G = GVarL (S .G ) (S .D )
@@ -45,17 +45,17 @@ struct
4545 S. sync man (`JoinCall f)
4646 | _ -> S. sync man `Join
4747
48- let common_man' var edge target_node pval (getl :lv -> ld ) sidel getg sideg : (D.t, S.G.t, S.C.t, S.V.t) man * D.t list ref * (lval option * varinfo * exp list * D.t * bool) list ref =
48+ let common_man' ( var : node * Obj.t * Obj.t ) edge target_node pval (getl :lv -> ld ) sidel getg sideg : (D.t, S.G.t, S.C.t, S.V.t) man * D.t list ref * (lval option * varinfo * exp list * D.t * bool) list ref =
4949 let r = ref [] in
5050 let spawns = ref [] in
5151 (* now watch this ... *)
5252 let rec man =
5353 { ask = (fun (type a ) (q : a Queries.t ) -> S. query man q)
5454 ; emit = (fun _ -> failwith " emit outside MCP" )
5555 ; node = target_node
56- ; prev_node = fst var
57- ; control_context = (fun () -> snd var |> Obj. obj)
58- ; context = (fun () -> snd var |> Obj. obj)
56+ ; prev_node = Tuple3. first var
57+ ; control_context = (fun () -> Tuple3. second var |> Obj. obj)
58+ ; context = (fun () -> Tuple3. second var |> Obj. obj)
5959 ; edge = edge
6060 ; local = pval
6161 ; global = (fun g -> G. spec (getg (GVar. spec g)))
7272 match Cilfacade. find_varinfo_fundec f with
7373 | fd ->
7474 let c = S. context man fd d in
75- sidel (FunctionEntry fd, c) d
75+ (* Derive digest from abstract state *)
76+ let p = S.P. of_elt d in
77+ sidel (FunctionEntry fd, c, p) d
7678 | exception Not_found ->
7779 (* unknown function *)
7880 M. error ~category: Imprecise ~tags: [Category Unsound ] " Created a thread from unknown function %s" f.vname;
@@ -167,7 +169,7 @@ struct
167169 let d = S. branch man e tv in (* Force transfer function to be evaluated before dereferencing in common_join argument. *)
168170 common_join man d ! r ! spawns
169171
170- let tf_normal_call man lv e (f :fundec ) args getl sidel getg sideg =
172+ let tf_normal_call man lv e (f :fundec ) args getl ( sidel : lv -> ld -> unit ) getg sideg =
171173 let combine (cd , fc , fd ) =
172174 if M. tracing then M. traceli " combine" " local: %a" S.D. pretty cd;
173175 if M. tracing then M. trace " combine" " function: %a" S.D. pretty fd;
@@ -222,7 +224,13 @@ struct
222224 in
223225 let paths = S. enter man lv f args in
224226 let paths = List. map (fun (c ,v ) -> (c, S. context man f v, v)) paths in
225- List. iter (fun (c ,fc ,v ) -> if not (S.D. is_bot v) then sidel (FunctionEntry f, fc) v) paths;
227+ let sidel_entries (c ,fc ,v ) =
228+ if not (S.D. is_bot v) then begin
229+ let p = S.P. of_elt v in
230+ sidel (FunctionEntry f, fc, p) v
231+ end
232+ in
233+ List. iter sidel_entries paths;
226234 let paths = List. map (fun (c ,fc ,v ) ->
227235 let endvar = (GVar. return (f,fc)) in
228236 (c, fc, if S.D. is_bot v then v else G. return @@ getg endvar)) paths in
@@ -323,33 +331,33 @@ struct
323331 let d = S. skip man in (* Force transfer function to be evaluated before dereferencing in common_join argument. *)
324332 common_join man d ! r ! spawns
325333
326- let tf ((n ,c ) as var ) getl sidel getg sideg target_node edge d =
334+ let tf ((n ,c , p ) as var ) getl sidel getg sideg target_node edge d =
327335 begin match edge with
328336 | Assign (lv ,rv ) ->
329337 let r = tf_assign var edge target_node lv rv getl sidel getg sideg d in
330- sidel (target_node, Obj. obj c) r
338+ sidel (target_node, Obj. obj c, Obj. obj p ) r
331339 | VDecl (v ) ->
332340 let r = tf_vdecl var edge target_node v getl sidel getg sideg d in
333- sidel (target_node, Obj. obj c) r
341+ sidel (target_node, Obj. obj c, Obj. obj p ) r
334342 | Proc (r ,f ,ars ) ->
335343 let r = tf_proc var edge target_node r f ars getl sidel getg sideg d in
336- sidel (target_node, Obj. obj c) r
344+ sidel (target_node, Obj. obj c, Obj. obj p ) r
337345 | Entry f ->
338346 let r = tf_entry var edge target_node f getl sidel getg sideg d in
339- sidel (target_node, Obj. obj c) r
347+ sidel (target_node, Obj. obj c, Obj. obj p ) r
340348 | Ret (r ,fd ) ->
341349 let r = tf_ret var edge target_node r fd getl sidel getg sideg d in
342- sidel (target_node, Obj. obj c) r;
350+ sidel (target_node, Obj. obj c, Obj. obj p ) r;
343351 sideg (GVar. return (fd,Obj. obj c)) (G. create_return r)
344- | Test (p ,b ) ->
345- let r = tf_test var edge target_node p b getl sidel getg sideg d in
346- sidel (target_node, Obj. obj c) r
352+ | Test (e ,b ) ->
353+ let r = tf_test var edge target_node e b getl sidel getg sideg d in
354+ sidel (target_node, Obj. obj c, Obj. obj p ) r
347355 | ASM (_ , _ , _ ) ->
348356 let r = tf_asm var edge target_node getl sidel getg sideg d in
349- sidel (target_node, Obj. obj c) r
357+ sidel (target_node, Obj. obj c, Obj. obj p ) r
350358 | Skip ->
351359 let r = tf_skip var edge target_node getl sidel getg sideg d in
352- sidel (target_node, Obj. obj c) r
360+ sidel (target_node, Obj. obj c, Obj. obj p ) r
353361 end
354362
355363 type Goblint_backtrace.mark + = TfLocation of location
@@ -372,13 +380,13 @@ struct
372380 tf var getl sidel getg sideg target_node edge d
373381 )
374382
375- let tf_fwd value (v ,c ) (edges , u ) getl sidel getg sideg :unit =
383+ let tf_fwd value (v ,c , p ) (edges , u ) getl sidel getg sideg :unit =
376384 let pval = value in
377385 let _, locs = List. fold_right (fun (f ,e ) (t ,xs ) -> f, (f,t)::xs) edges (Node. location v,[] ) in
378- let es = List. map (tf (v,Obj. repr c) getl sidel getg sideg u) edges in
386+ let es = List. map (tf (v,Obj. repr c, Obj. repr p ) getl sidel getg sideg u) edges in
379387 List. iter2 (fun e l -> e pval l) es locs
380388
381- let tf value (v ,c ) (e ,u ) getl sidel getg sideg =
389+ let tf value (v ,c , p ) (e ,u ) getl sidel getg sideg =
382390 let old_node = ! current_node in
383391 let old_fd = Option. map Node. find_fundec old_node |? Cil. dummyFunDec in
384392 let new_fd = Node. find_fundec v in
@@ -393,12 +401,12 @@ struct
393401 if not (CilType.Fundec. equal old_fd new_fd) then
394402 Timing.Program. exit new_fd.svar.vname
395403 ) (fun () ->
396- tf_fwd value (v,c) (e,u) getl sidel getg sideg
404+ tf_fwd value (v,c,p ) (e,u) getl sidel getg sideg
397405 )
398406
399- let system (v ,c ) =
407+ let system (v ,c , p ) =
400408 let tf value getl sidel getg sideg =
401- let tf' eu = tf value (v,c) eu getl sidel getg sideg in
409+ let tf' eu = tf value (v,c,p ) eu getl sidel getg sideg in
402410 let xs = Cfg. next v in
403411 List. iter (fun eu -> tf' eu) xs
404412 in
0 commit comments