Skip to content

Commit cf9d190

Browse files
committed
Fix base must-writing all invalidated variables
set_many writes one after another, so they all end up in protection privatization's P set for example (although it cannot be observed by precision). Nevertheless, this is the morally correct thing to do: an unknown function may or may not write each argument.
1 parent 0d6d3a8 commit cf9d190

File tree

1 file changed

+16
-8
lines changed

1 file changed

+16
-8
lines changed

Diff for: src/analyses/base.ml

+16-8
Original file line numberDiff line numberDiff line change
@@ -2045,7 +2045,7 @@ struct
20452045
List.map mpt exps
20462046
)
20472047

2048-
let invalidate ?(deep=true) ~ctx (st:store) (exps: exp list): store =
2048+
let invalidate ~(must: bool) ?(deep=true) ~ctx (st:store) (exps: exp list): store =
20492049
if M.tracing && exps <> [] then M.tracel "invalidate" "Will invalidate expressions [%a]" (d_list ", " d_plainexp) exps;
20502050
if exps <> [] then M.info ~category:Imprecise "Invalidating expressions: %a" (d_list ", " d_exp) exps;
20512051
(* To invalidate a single address, we create a pair with its corresponding
@@ -2072,7 +2072,15 @@ struct
20722072
let vs = List.map (Tuple3.third) invalids' in
20732073
M.tracel "invalidate" "Setting addresses [%a] to values [%a]" (d_list ", " AD.pretty) addrs (d_list ", " VD.pretty) vs
20742074
);
2075-
set_many ~ctx st invalids'
2075+
(* copied from set_many *)
2076+
let f (acc: store) ((lval:AD.t),(typ:Cil.typ),(value:value)): store =
2077+
let acc' = set ~ctx acc lval typ value in
2078+
if must then
2079+
acc'
2080+
else
2081+
D.join acc acc'
2082+
in
2083+
List.fold_left f st invalids'
20762084

20772085

20782086
let make_entry ?(thread=false) (ctx:(D.t, G.t, C.t, V.t) Analyses.ctx) fundec args: D.t =
@@ -2211,8 +2219,8 @@ struct
22112219
in
22122220
(* TODO: what about escaped local variables? *)
22132221
(* invalidate arguments and non-static globals for unknown functions *)
2214-
let st' = invalidate ~deep:false ~ctx ctx.local shallow_addrs in
2215-
invalidate ~deep:true ~ctx st' deep_addrs
2222+
let st' = invalidate ~must:false ~deep:false ~ctx ctx.local shallow_addrs in
2223+
invalidate ~must:false ~deep:true ~ctx st' deep_addrs
22162224

22172225
let check_invalid_mem_dealloc ctx special_fn ptr =
22182226
let has_non_heap_var = AD.exists (function
@@ -2302,7 +2310,7 @@ struct
23022310
let invalidate_ret_lv st = match lv with
23032311
| Some lv ->
23042312
if M.tracing then M.tracel "invalidate" "Invalidating lhs %a for function call %s" d_plainlval lv f.vname;
2305-
invalidate ~deep:false ~ctx st [Cil.mkAddrOrStartOf lv]
2313+
invalidate ~must:true ~deep:false ~ctx st [Cil.mkAddrOrStartOf lv]
23062314
| None -> st
23072315
in
23082316
let addr_type_of_exp exp =
@@ -2636,14 +2644,14 @@ struct
26362644
| Int n when GobOption.exists (Z.equal Z.zero) (ID.to_int n) -> st
26372645
| Address ret_a ->
26382646
begin match eval_rv ~ctx st id with
2639-
| Thread a when ValueDomain.Threads.is_top a -> invalidate ~ctx st [ret_var]
2647+
| Thread a when ValueDomain.Threads.is_top a -> invalidate ~must:true ~ctx st [ret_var]
26402648
| Thread a ->
26412649
let v = List.fold VD.join (VD.bot ()) (List.map (fun x -> G.thread (ctx.global (V.thread x))) (ValueDomain.Threads.elements a)) in
26422650
(* TODO: is this type right? *)
26432651
set ~ctx st ret_a (Cilfacade.typeOf ret_var) v
2644-
| _ -> invalidate ~ctx st [ret_var]
2652+
| _ -> invalidate ~must:true ~ctx st [ret_var]
26452653
end
2646-
| _ -> invalidate ~ctx st [ret_var]
2654+
| _ -> invalidate ~must:true ~ctx st [ret_var]
26472655
in
26482656
let st' = invalidate_ret_lv st' in
26492657
Priv.thread_join (Analyses.ask_of_ctx ctx) (priv_getg ctx.global) id st'

0 commit comments

Comments
 (0)