Skip to content

Commit ae2f346

Browse files
committed
Implement vojdani privatization invariant_global based on protection
1 parent f03f252 commit ae2f346

File tree

1 file changed

+22
-2
lines changed

1 file changed

+22
-2
lines changed

src/analyses/basePriv.ml

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,28 @@ struct
829829
vf g;
830830
| _ -> ()
831831

832-
let invariant_global ask getg g =
833-
ValueDomain.invariant_global getg g
832+
let invariant_global (ask: Q.ask) getg g =
833+
let locks = ask.f (Q.MustProtectingLocks g) in (* TODO: read-write locks *)
834+
if LockDomain.MustLockset.is_all locks || LockDomain.MustLockset.is_empty locks then (* TODO: output unprotected invariant with empty lockset? *)
835+
Invariant.none
836+
else (
837+
let read_global g = getg g in (* TODO: read top for others? or at least those which might not have all same protecting locks? *)
838+
let inv = ValueDomain.invariant_global read_global g in
839+
(* Very conservative about multiple protecting mutexes: invariant is not claimed when any of them is held.
840+
It should be possible to be more precise because writes only happen with all of them held,
841+
but conjunction is unsound when one of the mutexes is temporarily unlocked.
842+
Hypothetical read-protection is also somehow relevant. *)
843+
LockDomain.MustLockset.fold (fun m acc ->
844+
if LockDomain.MustLock.equal m (LockDomain.MustLock.of_var LibraryFunctions.verifier_atomic_var) then
845+
acc
846+
else if ask.f (GhostVarAvailable (Locked m)) then (
847+
let var = WitnessGhost.to_varinfo (Locked m) in
848+
Invariant.(of_exp (Lval (GoblintCil.var var)) || acc) [@coverage off] (* bisect_ppx cannot handle redefined (||) *)
849+
)
850+
else
851+
Invariant.none
852+
) locks inv
853+
)
834854

835855
let invariant_vars ask getg st = protected_vars ask
836856
end

0 commit comments

Comments
 (0)