Skip to content

Commit b856dcd

Browse files
sim642michael-schwarz
authored andcommitted
Add explicit W set to base protection privatization
1 parent 569489e commit b856dcd

File tree

1 file changed

+38
-20
lines changed

1 file changed

+38
-20
lines changed

src/analyses/basePriv.ml

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -899,18 +899,25 @@ struct
899899
let name () = "P"
900900
end
901901

902-
(* W is implicitly represented by CPA domain *)
903-
module D = P
902+
(** May written variables. *)
903+
module W =
904+
struct
905+
include MayVars
906+
let name () = "W"
907+
end
908+
909+
module D = Lattice.Prod (P) (W)
904910

905911
module Wrapper = Wrapper (VD)
906912
module G = Wrapper.G
907913
module V = ProtectionBasedV.V
908914

909-
let startstate () = P.empty ()
915+
let startstate () = P.empty (), W.empty ()
910916

911917
let read_global (ask: Queries.ask) getg (st: BaseComponents (D).t) x =
912918
let getg = Wrapper.getg ask getg in
913-
if P.mem x st.priv then
919+
let (p, _) = st.priv in
920+
if P.mem x p then
914921
CPA.find x st.cpa
915922
else if Param.handle_atomic && ask.f MustBeAtomic then
916923
VD.join (CPA.find x st.cpa) (getg (V.unprotected x)) (* Account for previous unpublished unprotected writes in current atomic section. *)
@@ -921,28 +928,35 @@ struct
921928

922929
let write_global ?(invariant=false) (ask: Queries.ask) getg sideg (st: BaseComponents (D).t) x v =
923930
let sideg = Wrapper.sideg ask sideg in
924-
if not invariant then (
925-
if not (Param.handle_atomic && ask.f MustBeAtomic) then
926-
sideg (V.unprotected x) v; (* Delay publishing unprotected write in the atomic section. *)
927-
if !earlyglobs && not (ThreadFlag.is_currently_multi ask) then (* earlyglobs workaround for 13/60 *)
928-
sideg (V.protected x) v (* Also side to protected because with earlyglobs enter_multithreaded does not side everything to protected *)
929-
(* Unlock after invariant will still side effect refined value (if protected) from CPA, because cannot distinguish from non-invariant write since W is implicit. *)
930-
);
931+
let (p, w) = st.priv in
932+
let w' =
933+
if not invariant then (
934+
if not (Param.handle_atomic && ask.f MustBeAtomic) then
935+
sideg (V.unprotected x) v; (* Delay publishing unprotected write in the atomic section. *)
936+
if !earlyglobs && not (ThreadFlag.is_currently_multi ask) then (* earlyglobs workaround for 13/60 *)
937+
sideg (V.protected x) v; (* Also side to protected because with earlyglobs enter_multithreaded does not side everything to protected *)
938+
(* Unlock after invariant will still side effect refined value (if protected) from CPA, because cannot distinguish from non-invariant write since W is implicit. *)
939+
W.add x w
940+
)
941+
else
942+
w
943+
in
931944
if Param.handle_atomic && ask.f MustBeAtomic then
932-
{st with cpa = CPA.add x v st.cpa; priv = P.add x st.priv} (* Keep write local as if it were protected by the atomic section. *)
945+
{st with cpa = CPA.add x v st.cpa; priv = (P.add x p, w')} (* Keep write local as if it were protected by the atomic section. *)
933946
else if is_unprotected ask x then
934947
st
935948
else
936-
{st with cpa = CPA.add x v st.cpa; priv = P.add x st.priv}
949+
{st with cpa = CPA.add x v st.cpa; priv = (P.add x p, w')}
937950

938951
let lock ask getg st m = st
939952

940953
let unlock ask getg sideg (st: BaseComponents (D).t) m =
941954
let sideg = Wrapper.sideg ask sideg in
942955
let atomic = Param.handle_atomic && LockDomain.MustLock.equal m (LockDomain.MustLock.of_var LibraryFunctions.verifier_atomic_var) in
943-
(* TODO: what about G_m globals in cpa that weren't actually written? *)
944-
CPA.fold (fun x v (st: BaseComponents (D).t) ->
956+
let (_, w) = st.priv in
957+
W.fold (fun x (st: BaseComponents (D).t) ->
945958
if is_protected_by ask m x then ( (* is_in_Gm *)
959+
let v = CPA.find x st.cpa in
946960
(* Extra precision in implementation to pass tests:
947961
If global is read-protected by multiple locks,
948962
then inner unlock shouldn't yet publish. *)
@@ -951,14 +965,16 @@ struct
951965
if atomic then
952966
sideg (V.unprotected x) v; (* Publish delayed unprotected write as if it were protected by the atomic section. *)
953967

954-
if is_unprotected_without ask x m then (* is_in_V' *)
955-
{st with cpa = CPA.remove x st.cpa; priv = P.remove x st.priv}
968+
if is_unprotected_without ask x m then ( (* is_in_V' *)
969+
let (p, w) = st.priv in
970+
{st with cpa = CPA.remove x st.cpa; priv = (P.remove x p, W.remove x w)}
971+
)
956972
else
957973
st
958974
)
959975
else
960976
st
961-
) st.cpa st
977+
) w st
962978

963979
let sync ask getg sideg (st: BaseComponents (D).t) reason =
964980
let branched_sync () =
@@ -968,7 +984,8 @@ struct
968984
if is_global ask x && is_unprotected ask x then (
969985
sideg (V.unprotected x) v;
970986
sideg (V.protected x) v; (* must be like enter_multithreaded *)
971-
{st with cpa = CPA.remove x st.cpa; priv = P.remove x st.priv}
987+
let (p, w) = st.priv in
988+
{st with cpa = CPA.remove x st.cpa; priv = (P.remove x p, W.remove x w)}
972989
)
973990
else
974991
st
@@ -1007,7 +1024,8 @@ struct
10071024
if is_global ask x then (
10081025
sideg (V.unprotected x) v;
10091026
sideg (V.protected x) v;
1010-
{st with cpa = CPA.remove x st.cpa; priv = P.remove x st.priv}
1027+
let (p, w) = st.priv in
1028+
{st with cpa = CPA.remove x st.cpa; priv = (P.remove x p, W.remove x w)}
10111029
)
10121030
else
10131031
st

0 commit comments

Comments
 (0)