@@ -52,36 +52,56 @@ let is_thread_local base =
5252      end 
5353    |  _  -> false 
5454
55- (* 
56- class is_referenced = object 
57-   inherit Visitor.frama_in_place 
55+ let  cache =  ref  (None  : Varinfo.Set.t option )
5856
59-   module M = Base.Map 
57+ class  escapes_expr  =  object 
58+   inherit  Visitor. frama_c_inplace
6059
61-   val mutable cache = M.empty 
62-   val mutable res = (None : bool option) 
60+   method!  vexpr e =  match  (Cil. stripCasts e).enode with 
61+     |  AddrOf  (Var v , _ ) -> begin  match  ! cache with 
62+       |  None  -> failwith " Internal error" 
63+       |  Some  c  ->
64+         Logger. debug ~level: 5  " Adding escaping variable: %a" Varinfo. pretty v;
65+         cache :=  Some  (Varinfo.Set. add v c); DoChildren 
6366
64-   method! vexpr e = match e.enode with 
65-     | Lval (Var var', NoOffset) -> 
66-       if Varinfo.equal var var' then ChangeTo {e with enode = Const const} 
67-       else DoChildren 
67+       end 
6868    |  _  -> DoChildren 
6969
70- let is_referenced = 
71-   let cache := ref M.empty in 
72-   fun base -> 
73-     try M.find base !cache 
74-     with Not_found -> 
70+  end 
7571
76- 
77- class substitution = object 
72+ class  is_referenced_visitor  =  object 
7873  inherit  Visitor. frama_c_inplace
79- *) 
80- (* * Very simple approximation of escape analysis:
81-     - All referenced variables can escape 
82-     - All dynamically allocated bases can escape *)  
74+ 
75+   method!  vstmt stmt = 
76+     let  exprs =  match  stmt.skind with 
77+       |  Instr  (Set (lval , expr , _ )) -> [expr]
78+       |  Instr  (Call (_ , {enode  = Lval  (Var fn , NoOffset); _} , exprs , _ )) ->
79+         if  ConcurrencyModel. is_atomic_fn fn then  [] 
80+         else  exprs
81+       |  Instr  (Call (_ , _ , exprs , _ )) -> exprs
82+       |  Instr  (Local_init (_ , ConsInit (fn , exprs , _ ), _ )) ->
83+         if  ConcurrencyModel. is_atomic_fn fn then  [] 
84+         else  exprs
85+       |  _  -> [] 
86+     in 
87+     let  check_expr =  (fun  e  -> ignore @@  (new  escapes_expr)#vexpr e) in 
88+     List. iter check_expr exprs;
89+     DoChildren 
90+ 
91+ end 
92+ 
93+ let  is_referenced  var  = 
94+   match  ! cache with 
95+   |  None  ->
96+     let  _ =   cache :=  Some  Varinfo.Set. empty in 
97+     let  file =  Ast. get ()  in 
98+     let  _  =  Visitor. visitFramacFileSameGlobals (new  is_referenced_visitor) file in 
99+     Varinfo.Set. mem var (Option. get ! cache)
100+   |  Some  _  -> Varinfo.Set. mem var (Option. get ! cache)
101+ 
102+ (* * Simple  escape analysis *) 
83103let  may_escape  =  function 
84-   |  Var  (var , _ ) -> var.vaddrof 
104+   |  Var  (var , _ ) -> is_referenced  var
85105  |  Allocated  (var , _ , _ ) -> true 
86106    (* 
87107    begin match Cil_utils.find_allocation_target var with 
0 commit comments