@@ -48,6 +48,8 @@ open CCHPreFileIO
4848open CCHPreTypes
4949open CCHProofScaffolding
5050
51+ module H = Hashtbl
52+
5153
5254let fenv = CCHFileEnvironment. file_environment
5355
@@ -60,7 +62,7 @@ object (self)
6062 method private ftype = self#f.svar.vtype
6163
6264 method private fname = self#f.svar.vname
63-
65+
6466 method private pointer_parameters = pointer_parameters
6567
6668 method private env = self#f.sdecls
@@ -142,16 +144,39 @@ object (self)
142144 let _ = self#spomanager#add_return loc context#add_return e in
143145 begin
144146 (match e with
145- | Some x -> self#create_po_exp context#add_return x loc
147+ | Some x ->
148+ begin
149+ self#create_po_exp context#add_return x loc;
150+ (match type_of_exp self#env x with
151+ | TPtr _ -> self#add_ppo (PValidMem x) loc context
152+ | _ -> () )
153+ end
146154 | _ -> () );
147155 (List. iter (fun vinfo ->
148- begin
149- self#add_ppo
150- (POutputParameterInitialized vinfo) loc context#add_return;
151- self#add_ppo
152- (POutputParameterUnaltered vinfo) loc context#add_return
153- end )
154- self#pointer_parameters)
156+ let vty = fenv#get_type_unrolled vinfo.vtype in
157+ (match vty with
158+ | TPtr (ty , _ ) ->
159+ if is_integral_type ty then
160+ begin
161+ self#add_ppo
162+ (POutputParameterInitialized (vinfo, NoOffset ))
163+ loc context#add_return;
164+ self#add_ppo
165+ (POutputParameterUnaltered (vinfo, NoOffset ))
166+ loc context#add_return
167+ end
168+ else if is_scalar_struct_type ty then
169+ let offsets = get_scalar_struct_offsets ty in
170+ List. iter (fun offset ->
171+ begin
172+ self#add_ppo
173+ (POutputParameterInitialized (vinfo, offset))
174+ loc context#add_return;
175+ self#add_ppo
176+ (POutputParameterUnaltered (vinfo, offset))
177+ loc context#add_return
178+ end ) offsets
179+ | _ -> () )) self#pointer_parameters)
155180 end
156181
157182 method private create_po_instr (context : program_context_int ) (i : instr ) =
@@ -192,7 +217,10 @@ object (self)
192217 end );
193218 (List. iteri (fun i x ->
194219 let newcontext = context#add_arg (i + 1 ) in
195- self#create_po_exp newcontext x loc) el)
220+ begin
221+ self#create_po_exp newcontext x loc;
222+ self#add_ppo (PValidMem x) loc newcontext
223+ end ) el)
196224 end
197225
198226 method private create_po_exp
@@ -215,12 +243,20 @@ object (self)
215243 let cinfo = fenv#get_comp tckey in
216244 begin
217245 List. iter (fun f ->
218- self#add_ppo
219- (PInitialized
220- (Var (vname, vid), Field ((f.fname, f.fckey), NoOffset )))
221- loc
222- context)
223- cinfo.cfields;
246+ begin
247+ self#add_ppo
248+ (PInitialized
249+ (Var (vname, vid), Field ((f.fname, f.fckey), NoOffset )))
250+ loc
251+ context;
252+ (List. iter (fun pvinfo ->
253+ self#add_ppo
254+ (PLocallyInitialized
255+ (pvinfo,
256+ (Var (vname, vid),
257+ Field ((f.fname, f.fckey), NoOffset )))) loc context)
258+ self#pointer_parameters)
259+ end ) cinfo.cfields;
224260 self#create_po_lval context#add_lval (Var (vname, vid), NoOffset ) loc
225261 end
226262 | _ -> ()
@@ -231,6 +267,7 @@ object (self)
231267
232268 | Lval lval ->
233269 begin
270+ self#add_ppo (PInitialized lval) loc context;
234271 (List. iter (fun vinfo ->
235272 self#add_ppo (PLocallyInitialized (vinfo, lval)) loc context)
236273 self#pointer_parameters);
@@ -275,7 +312,21 @@ object (self)
275312 | Var (_vname , vid ) ->
276313 let ty = (self#env#get_varinfo_by_vid vid).vtype in
277314 self#create_po_offset context#add_var offset ty loc
278- | Mem e -> self#create_po_exp context#add_mem e loc
315+ | Mem e ->
316+ let tgttyp =
317+ let t = type_of_exp self#env e in
318+ match t with
319+ | TPtr (tt , _ ) -> tt
320+ | _ -> TVoid [] in
321+ begin
322+ self#create_po_exp context#add_mem e loc;
323+ self#create_po_dereference context#add_mem e loc;
324+ self#create_po_offset context#add_mem offset tgttyp loc
325+ end
326+
327+ method private create_po_dereference
328+ (context : program_context_int ) (e : exp ) (loc : location ) =
329+ self#add_ppo (PValidMem e) loc context
279330
280331 method private create_po_offset
281332 (context : program_context_int )
@@ -294,7 +345,7 @@ object (self)
294345 else
295346 ()
296347 | _ -> () )
297-
348+
298349 | Index (exp , oo ) ->
299350 (match fenv#get_type_unrolled hosttyp with
300351 | TArray (tt , Some _len , _ ) ->
@@ -303,7 +354,7 @@ object (self)
303354 self#create_po_offset context#add_index_offset oo tt loc
304355 end
305356 | _ -> () )
306-
357+
307358 method private create_po_binop
308359 (_context : program_context_int )
309360 (_binop : binop )
@@ -314,7 +365,7 @@ object (self)
314365 ()
315366
316367end
317-
368+
318369
319370let process_function (fname :string ) =
320371 let _ = log_info " Process function %s [%s:%d]" fname __FILE__ __LINE__ in
@@ -337,6 +388,8 @@ let process_function (fname:string) =
337388 if (List. length pointer_parameters) > 0 then
338389 begin
339390 read_proof_files fname fdecls;
391+ CCHProofScaffolding. proof_scaffolding#set_analysis_info
392+ fname (OutputParameterInfo pointer_parameters);
340393 (new po_creator_t fundec pointer_parameters)#create_proof_obligations;
341394 CCHCheckValid. process_function fname;
342395 save_proof_files fname;
@@ -384,3 +437,63 @@ let output_parameter_po_process_file () =
384437 with
385438 | CHXmlReader. IllFormed ->
386439 ch_error_log#add " ill-formed content" (STR system_settings#get_cfilename)
440+
441+
442+ let output_parameter_analysis_is_active
443+ (fname : string )
444+ (vinfos : varinfo list )
445+ (po_s : proof_obligation_int list ): bool =
446+ let vinfo_po_s = H. create (List. length vinfos) in
447+ let _ = List. iter (fun vinfo -> H. add vinfo_po_s vinfo.vname [] ) vinfos in
448+ let _ =
449+ List. iter (fun po ->
450+ match po#get_predicate with
451+ | PLocallyInitialized (vinfo, _)
452+ | POutputParameterInitialized (vinfo, _)
453+ | POutputParameterUnaltered (vinfo , _ ) ->
454+ let entry =
455+ try
456+ H. find vinfo_po_s vinfo.vname
457+ with
458+ | Not_found ->
459+ raise (CCHFailure (LBLOCK [STR __FILE__; STR " :" ; INT __LINE__])) in
460+ H. replace vinfo_po_s vinfo.vname (po :: entry)
461+ | _ -> () ) po_s in
462+ let vinfo_is_active (vname : string ): bool =
463+ let vpo_s = H. find vinfo_po_s vname in
464+ let read_violation =
465+ List. exists (fun po ->
466+ match po#get_predicate with
467+ | PLocallyInitialized _ -> po#is_violation
468+ | _ -> false ) vpo_s in
469+ let op_violation =
470+ let op_ctxts = H. create 3 in
471+ let add_ctxt (index : int ) (po : proof_obligation_int ) =
472+ let entry =
473+ if H. mem op_ctxts index then
474+ H. find op_ctxts index
475+ else
476+ begin
477+ H. add op_ctxts index [] ;
478+ []
479+ end in
480+ H. replace op_ctxts index (po :: entry) in
481+ let _ =
482+ List. iter (fun po ->
483+ match po#get_predicate with
484+ | POutputParameterInitialized _
485+ | POutputParameterUnaltered _ ->
486+ add_ctxt po#get_context#get_cfg_context#index po
487+ | _ -> () ) vpo_s in
488+ List. exists (fun index ->
489+ List. for_all (fun po -> po#is_violation) (H. find op_ctxts index))
490+ (H. fold (fun k _ a -> k :: a) op_ctxts [] ) in
491+ (not read_violation)
492+ && (not op_violation)
493+ && (List. exists (fun po -> not po#is_closed) vpo_s) in
494+ let active =
495+ List. exists vinfo_is_active (List. map (fun vinfo -> vinfo.vname) vinfos) in
496+ let _ =
497+ if not active then
498+ CHTiming. pr_timing [STR " deactivating analysis of " ; STR fname] in
499+ active
0 commit comments