@@ -13,6 +13,8 @@ open Analyses
1313
1414module VarSet = SetDomain. Make (Basetype. Variables )
1515
16+ type access_kind = Read | Write
17+
1618module Spec =
1719struct
1820 module Arg =
@@ -72,23 +74,22 @@ struct
7274 (* * Collects information about which variables are protected by which mutexes *)
7375 module GProtecting : sig
7476 include Lattice. S
75- val make : kind :Queries . ProtectionKind . t -> recovered :bool -> MustLockset .t -> t
77+ val make : kind :access_kind -> recovered :bool -> MustLockset .t -> t
7678 val get : kind :Queries .ProtectionKind .t -> Queries.Protection .t -> t -> MustLockset .t
7779 end = struct
7880 include MakeP (MustLockset )
7981
80- let make ~kind ~recovered locks =
81- (* If the access is not a write, set to T so intersection with current write-protecting is identity *)
82- let wlocks =
82+ let make ~(kind : access_kind ) ~recovered locks =
83+ let locks =
8384 match kind with
84- | Queries.ProtectionKind. Write -> locks
85- | ReadWrite -> MustLockset. all ()
85+ | Write -> ( locks, locks)
86+ | Read -> (locks, MustLockset. all () ) (* If the access is not a write, set to T so intersection with current write-protecting is identity * )
8687 in
8788 if recovered then
8889 (* If we are in single-threaded mode again, this does not need to be added to set of mutexes protecting in mt-mode only *)
89- (( locks, wlocks) , (MustLockset. all () , MustLockset. all () ))
90+ (locks, (MustLockset. all () , MustLockset. all () ))
9091 else
91- (( locks, wlocks), ( locks, wlocks) )
92+ (locks, locks)
9293 end
9394
9495
@@ -299,24 +300,33 @@ struct
299300 if not (MustLocksetRW. is_all (fst oman.local)) then
300301 let locks = MustLocksetRW. to_must_lockset (MustLocksetRW. filter snd (fst oman.local)) in
301302 let kind = match kind with
302- | Write | Free -> Queries.ProtectionKind. Write
303- | Read -> ReadWrite
303+ | Write | Free -> Write
304+ | Read -> Read
304305 | Call
305- | Spawn -> ReadWrite (* TODO: nonsense? *)
306+ | Spawn -> Read (* TODO: nonsense? *)
306307 in
307308 let s = GProtecting. make ~kind ~recovered: is_recovered_to_st locks in
308309 man.sideg (V. protecting v) (G. create_protecting s);
309310
310311 if ! AnalysisState. postsolving then (
311- let protecting mode = GProtecting. get ~kind mode (G. protecting (man.global (V. protecting v))) in
312- let held_strong = protecting Strong in
313- let held_weak = protecting Weak in
314- let vs = VarSet. singleton v in
315- let protected = G. create_protected @@ GProtected. make ~kind vs in
316- MustLockset. iter (fun ml -> man.sideg (V. protected ml) protected) held_strong;
317- (* If the mutex set here is top, it is actually not accessed *)
318- if is_recovered_to_st && not @@ MustLockset. is_all held_weak then
319- MustLockset. iter (fun ml -> man.sideg (V. protected ml) protected) held_weak;
312+ let side_protected kind mode =
313+ let protecting = GProtecting. get ~kind mode (G. protecting (man.global (V. protecting v))) in
314+ (* If the mutex set here is top, it is actually not accessed *)
315+ if not @@ MustLockset. is_all protecting then (
316+ let vs = VarSet. singleton v in
317+ let protected = G. create_protected @@ GProtected. make ~kind vs in
318+ MustLockset. iter (fun ml -> man.sideg (V. protected ml) protected) protecting
319+ )
320+ in
321+ let side_protected kind =
322+ side_protected kind Strong ;
323+ if is_recovered_to_st then
324+ side_protected kind Weak
325+ in
326+ side_protected Queries.ProtectionKind. ReadWrite ;
327+ match kind with
328+ | Write -> side_protected Queries.ProtectionKind. Write
329+ | Read -> ()
320330 )
321331 | None -> M. info ~category: Unsound " Write to unknown address: privatization is unsound."
322332 in
0 commit comments