@@ -85,6 +85,17 @@ struct
8585
8686 let refine_lv man st c x c' pretty exp =
8787 let set' lval v st = set st (eval_lv ~man st lval) (Cilfacade. typeOfLval lval) ~lval_raw: lval v ~man in
88+ let default () =
89+ (* For accesses via pointers in complicated case, no refinement yet *)
90+ let old_val = eval_rv_lval_refine ~man st exp x in
91+ let old_val = map_oldval old_val (Cilfacade. typeOfLval x) in
92+ let v = apply_invariant ~old_val ~new_val: c' in
93+ if is_some_bot v then contra st
94+ else (
95+ if M. tracing then M. tracel " inv" " improve lval %a from %a to %a (c = %a, c' = %a)" d_lval x VD. pretty old_val VD. pretty v pretty c VD. pretty c';
96+ set' x v st
97+ )
98+ in
8899 match x with
89100 | Var var , o when refine_entire_var ->
90101 (* For variables, this is done at to the level of entire variables to benefit e.g. from disjunctive struct domains *)
@@ -100,23 +111,28 @@ struct
100111 if M. tracing then M. tracel " inv" " st from %a to %a" D. pretty st D. pretty r;
101112 r
102113 )
103- | Mem (Lval lv ), NoOffset ->
104- let lvals = eval_lv ~man st x in
114+ | Mem (Lval lv ), off ->
115+ let lvals = eval_lv ~man st ( Mem ( Lval lv), off) in
105116 let res = AD. fold (fun a acc ->
106- if M. tracing then M. tracel " inv" " Consider case of lval %a = %a" d_lval lv VD. pretty (Address (AD. singleton a));
107- let st = set' lv (Address (AD. singleton a)) st in
108- let old_val = get ~man st (AD. singleton a) None in
109- let old_val = VD. cast (Cilfacade. typeOfLval x) old_val in (* needed as the type of this pointer may be different *)
110- (* this what I would originally have liked to do, but eval_rv_lval_refine uses queries and thus stale values *)
111- (* let old_val = eval_rv_lval_refine ~man st exp x in *)
112- let old_val = map_oldval old_val (Cilfacade. typeOfLval x) in
113- let v = apply_invariant ~old_val ~new_val: c' in
114- if is_some_bot v then
115- D. join acc (try contra st with Analyses. Deadcode -> D. bot () )
116- else (
117- if M. tracing then M. tracel " inv" " improve lval %a from %a to %a (c = %a, c' = %a)" d_lval x VD. pretty old_val VD. pretty v pretty c VD. pretty c';
118- D. join acc (set' x v st)
119- )
117+ match a with
118+ | Addr (base , _ ) as orig ->
119+ let (a:VD.t ) = Address (AD. singleton (AD.Addr. of_var base)) in
120+ if M. tracing then M. tracel " invo" " Consider case of lval %a = %a" d_lval lv VD. pretty a;
121+ let st = set' lv a st in
122+ let old_val = get ~man st (AD. singleton orig) None in
123+ let old_val = VD. cast (Cilfacade. typeOfLval x) old_val in (* needed as the type of this pointer may be different *)
124+ (* this what I would originally have liked to do, but eval_rv_lval_refine uses queries and thus stale values *)
125+ (* let old_val = eval_rv_lval_refine ~man st exp x in *)
126+ let old_val = map_oldval old_val (Cilfacade. typeOfLval x) in
127+ let v = apply_invariant ~old_val ~new_val: c' in
128+ if is_some_bot v then
129+ D. join acc (try contra st with Analyses. Deadcode -> D. bot () )
130+ else (
131+ if M. tracing then M. tracel " invo" " improve lval %a from %a to %a (c = %a, c' = %a)" d_lval x VD. pretty old_val VD. pretty v pretty c VD. pretty c';
132+ D. join acc (set' x v st)
133+ )
134+ | _ ->
135+ default ()
120136 ) lvals (D. bot () )
121137 in
122138 if D. is_bot res then
@@ -125,15 +141,8 @@ struct
125141 res
126142 | Var _, _
127143 | Mem _ , _ ->
128- (* For accesses via pointers, not yet *)
129- let old_val = eval_rv_lval_refine ~man st exp x in
130- let old_val = map_oldval old_val (Cilfacade. typeOfLval x) in
131- let v = apply_invariant ~old_val ~new_val: c' in
132- if is_some_bot v then contra st
133- else (
134- if M. tracing then M. tracel " inv" " improve lval %a from %a to %a (c = %a, c' = %a)" d_lval x VD. pretty old_val VD. pretty v pretty c VD. pretty c';
135- set' x v st
136- )
144+ default ()
145+
137146
138147 let invariant_fallback man st exp tv =
139148 (* We use a recursive helper function so that x != 0 is false can be handled
0 commit comments