@@ -30,6 +30,7 @@ open CHPretty
3030open CHUtils
3131
3232(* chtuil *)
33+ open CHLogger
3334open CHTimingLog
3435open CHTraceResult
3536
@@ -48,9 +49,11 @@ open CCHPreTypes
4849open CCHProofScaffolding
4950
5051module H = Hashtbl
52+ module TR = CHTraceResult
53+
5154let (let* ) x f = CHTraceResult. tbind f x
5255
53- let result_of_option (msg : string ) (o : 'a option ): ('a, string list) result =
56+ let result_of_option (msg : string ) (o : 'a option ): ('a, string list) result =
5457 match o with
5558 | None -> Error [msg]
5659 | Some r -> Ok r
@@ -65,11 +68,23 @@ let is_errno_location_call (e:exp): bool =
6568 | _ -> false
6669
6770let is_int_ptr (env : cfundeclarations_int ) (v : int ): bool =
68- let ty = (env#get_varinfo_by_vid v).vtype in
69- let ty_unroll = CCHFileEnvironment. file_environment#get_type_unrolled ty in
70- match ty_unroll with
71- | TPtr (TInt _ , _ ) -> true
72- | _ -> false
71+ TR. tfold
72+ ~ok: (fun vinfo ->
73+ let ty = vinfo.vtype in
74+ let ty_unroll = CCHFileEnvironment. file_environment#get_type_unrolled ty in
75+ match ty_unroll with
76+ | TPtr (TInt _ , _ ) -> true
77+ | _ -> false )
78+ ~error: (fun err ->
79+ begin
80+ log_error_result
81+ ~tag: " is_int_ptr"
82+ ~msg: env#functionname
83+ __FILE__ __LINE__
84+ [String. concat " , " err];
85+ false
86+ end )
87+ (env#get_varinfo_by_vid v)
7388
7489(* Collect all pointers `x` from a target expression that have non-deref uses *)
7590class pointer_use_expr_walker_t (env :cfundeclarations_int ) =
@@ -93,9 +108,9 @@ let blacklistable_pointers_of_exp (env: cfundeclarations_int) (e: exp): int list
93108 let walker = new pointer_use_expr_walker_t env in
94109 let _ = walker#walk_exp e in
95110 walker#get_vars
96-
97- (* Collect all variables that must alias __errno_location(). This fails if
98- we see anything that makes this analysis non-trivial,
111+
112+ (* Collect all variables that must alias __errno_location(). This fails if
113+ we see anything that makes this analysis non-trivial,
99114 like x = __errno_location(); y = x; ... *)
100115class errno_location_block_walker_t (env :cfundeclarations_int ) =
101116object (self )
@@ -104,29 +119,29 @@ object (self)
104119 (* vids *)
105120 val errno_pointers = new IntCollections. set_t
106121
107- (*
122+ (*
108123 These are vids of pointers, x, whose uses in the program are anything _EXCEPT_
109124 1) x = __errno_location()
110125 2) *x
111126
112127 e.g. the following instructions or expressions would result in adding x
113128 to this set:
114- y = x, x + 1,
129+ y = x, x + 1,
115130 *)
116131 val blacklist_pointers = new IntCollections. set_t
117132
118133 method invalid_errno_uses : IntCollections. set_t =
119134 errno_pointers#inter blacklist_pointers
120-
135+
121136 method errno_pointers : IntCollections. set_t = errno_pointers
122137
123138 method! walk_instr (i:instr ) =
124139 match i with
125- | Call (Some (Var x , _ ), f , [] , _ ) when is_errno_location_call f ->
140+ | Call (Some (Var x , _ ), f , [] , _ ) when is_errno_location_call f ->
126141 self#add_errno_pointer (snd x);
127142 super#walk_instr i
128143
129- | _ ->
144+ | _ ->
130145 super#walk_instr i
131146
132147 method! walk_rhs (e:exp ) = self#blacklist_exp_ptrs e
@@ -146,15 +161,15 @@ object (self)
146161end
147162
148163(* Check that we can easily track aliases of __errno_location() *)
149- let check_errno_pointer_uses_in_block (env : cfundeclarations_int ) (b : block ) =
164+ let check_errno_pointer_uses_in_block (env : cfundeclarations_int ) (b : block ) =
150165 let block_walker = new errno_location_block_walker_t env in
151166 let _ = block_walker#walk_block b in
152167 if (block_walker#invalid_errno_uses)#isEmpty then
153168 Some (block_walker#errno_pointers)
154169 else
155170 None
156171
157- (* At every *read* of errno, check that we *must* observe a known local write, where
172+ (* At every *read* of errno, check that we *must* observe a known local write, where
158173 such a write is either:
159174 1) a direct assignment (e.g. errno = 0)
160175 2) a write due to a library call (e.g. fopen in the branch where fopen returned NULL)
@@ -169,7 +184,7 @@ object (self)
169184 self#create_po_block (mk_program_context () ) self#f.sbody
170185
171186 method private create_po_block (context : program_context_int ) (b : block ): unit =
172- List. iter (fun s -> self#create_po_stmt (context#add_stmt s.sid) s) b.bstmts
187+ List. iter (fun s -> self#create_po_stmt (context#add_stmt s.sid) s) b.bstmts
173188
174189 method private create_po_stmt (context : program_context_int ) (s : stmt ): unit =
175190 self#create_po_stmtkind context s.skind
@@ -203,33 +218,33 @@ object (self)
203218 | Break _
204219 | Continue _
205220 | Goto _ -> ()
206- | TryFinally _
221+ | TryFinally _
207222 | TryExcept _ ->
208223 pr_debug [ STR " Errno analysis does not currently support TryFinally or TryExcept " ]
209224
210225 method private create_po_instr (context : program_context_int ) (i : instr ): unit =
211226 match i with
212227 | Set (_ , e , loc ) -> self#create_po_exp context#add_rhs e loc
213- | Call (ret , callee , args , loc ) ->
228+ | Call (ret , callee , args , loc ) ->
214229 begin
215230 self#create_po_exp context#add_ftarget callee loc;
216231 (match ret with
217232 | None -> ()
218233 | Some r -> self#create_po_lval context#add_lhs r loc);
219234 List. iteri (fun i e -> self#create_po_exp (context#add_arg (i+ 1 )) e loc) args;
220235 end
221- | VarDecl _
236+ | VarDecl _
222237 | Asm _ -> ()
223238
224239 method create_po_exp (context : program_context_int ) (e : exp ) (loc : location ) =
225240 match e with
226- | Lval (Mem (Lval (Var x , NoOffset)), NoOffset) when errno_aliases#has (snd x) ->
241+ | Lval (Mem (Lval (Var x , NoOffset)), NoOffset) when errno_aliases#has (snd x) ->
227242 self#add_ppo PErrnoWritten loc context;
228243 | Lval (Mem e , _ ) -> self#create_po_exp context#add_lval#add_mem e loc
229244 | Lval (Var _ , _ ) -> ()
230245 | UnOp (_ , e , _ ) -> self#create_po_exp context#add_unop e loc
231- | BinOp (_ , e1 , e2 , _ ) ->
232- begin
246+ | BinOp (_ , e1 , e2 , _ ) ->
247+ begin
233248 self#create_po_exp (context#add_binop 1 ) e1 loc;
234249 self#create_po_exp (context#add_binop 2 ) e2 loc;
235250 end
@@ -252,7 +267,7 @@ object (self)
252267 | AddrOfLabel _
253268 | SizeOfE _ -> ()
254269
255- method private create_po_lval context lval loc : unit =
270+ method private create_po_lval context lval loc : unit =
256271 match lval with
257272 | (Var _ , _ ) -> ()
258273 | (Mem e , _ ) -> self#create_po_exp context#add_mem e loc
@@ -268,7 +283,7 @@ let process_function (fname:string): unit traceresult =
268283 let _ = log_info " Process function %s [%s:%d]" fname __FILE__ __LINE__ in
269284 let fundec = read_function_semantics fname in
270285 let _ = read_proof_files fname fundec.sdecls in
271- let * errnos = check_errno_pointer_uses_in_block fundec.sdecls fundec.sbody
286+ let * errnos = check_errno_pointer_uses_in_block fundec.sdecls fundec.sbody
272287 |> result_of_option " Can not run errno analysis, found code we can not analyze"
273288 in
274289 let _ = (new po_creator_t fundec errnos)#create_proof_obligations in
0 commit comments