Skip to content

Commit 90dc841

Browse files
committed
CHC: add offset to output-parameter predicates
1 parent d2fb398 commit 90dc841

File tree

6 files changed

+208
-39
lines changed

6 files changed

+208
-39
lines changed

CodeHawk/CHC/cchpre/cCHCreateOutputParameterPOs.ml

Lines changed: 133 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ open CCHPreFileIO
4848
open CCHPreTypes
4949
open CCHProofScaffolding
5050

51+
module H = Hashtbl
52+
5153

5254
let 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

316367
end
317-
368+
318369

319370
let 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

CodeHawk/CHC/cchpre/cCHCreateOutputParameterPOs.mli

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,10 @@
2727

2828

2929
val output_parameter_po_process_file: unit -> unit
30+
31+
32+
val output_parameter_analysis_is_active:
33+
string
34+
-> CCHBasicTypes.varinfo list
35+
-> CCHPreTypes.proof_obligation_int list
36+
-> bool

CodeHawk/CHC/cchpre/cCHPOPredicate.ml

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ object (self)
125125
let wt = self#walk_type in
126126
let wl = self#walk_lval in
127127
let wv = self#walk_varinfo in
128+
let wo = self#walk_offset in
128129
match p with
129130
| PNotNull e | PNull e | PValidMem e | PInScope e
130131
| PControlledResource (_, e)
@@ -246,8 +247,16 @@ object (self)
246247
| PPreservedAllMemory -> ()
247248
| PPreservedAllMemoryX l -> List.iteri (fun i e -> we (i+1) e) l
248249
| PContractObligation _ -> ()
249-
| POutputParameterInitialized v -> wv 1 v
250-
| POutputParameterUnaltered v -> wv 1 v
250+
| POutputParameterInitialized (v, o) ->
251+
begin
252+
wv 1 v;
253+
wo 2 o
254+
end
255+
| POutputParameterUnaltered (v, o) ->
256+
begin
257+
wv 1 v;
258+
wo 2 o
259+
end
251260

252261
end
253262

@@ -635,10 +644,20 @@ let po_predicate_to_full_pretty p =
635644
STR "preserved-all-memory-x";
636645
pretty_print_list l exp_to_pretty "(" "," ")"]
637646
| PContractObligation s -> LBLOCK [STR "contract-obligation:"; STR s]
638-
| POutputParameterInitialized vinfo ->
639-
LBLOCK [STR "outputparameter-initialized("; STR vinfo.vname; STR ")"]
640-
| POutputParameterUnaltered vinfo ->
641-
LBLOCK [STR "outputparameter-unaltered("; STR vinfo.vname; STR ")"]
647+
| POutputParameterInitialized (vinfo, offset) ->
648+
LBLOCK [
649+
STR "outputparameter-initialized(";
650+
STR vinfo.vname;
651+
STR ", ";
652+
offset_to_pretty offset;
653+
STR ")"]
654+
| POutputParameterUnaltered (vinfo, offset) ->
655+
LBLOCK [
656+
STR "outputparameter-unaltered(";
657+
STR vinfo.vname;
658+
STR ", ";
659+
offset_to_pretty offset;
660+
STR ")"]
642661

643662

644663
let pr_expr op e1 e2 t = exp_to_pretty (BinOp (op, e1, e2,t ))
@@ -864,10 +883,20 @@ let po_predicate_to_pretty ?(full=false) (p:po_predicate_t) =
864883
STR "preserved-all-memory-x";
865884
pretty_print_list l exp_to_pretty "(" "," ")"]
866885
| PContractObligation s -> LBLOCK [STR "contract-obligation:"; STR s]
867-
| POutputParameterInitialized vinfo ->
868-
LBLOCK [STR "outputparameter-initialized("; STR vinfo.vname; STR ")"]
869-
| POutputParameterUnaltered vinfo ->
870-
LBLOCK [STR "outputparameter-unaltered("; STR vinfo.vname; STR ")"]
886+
| POutputParameterInitialized (vinfo, offset) ->
887+
LBLOCK [
888+
STR "outputparameter-initialized(";
889+
STR vinfo.vname;
890+
STR ", ";
891+
offset_to_pretty offset;
892+
STR ")"]
893+
| POutputParameterUnaltered (vinfo, offset) ->
894+
LBLOCK [
895+
STR "outputparameter-unaltered(";
896+
STR vinfo.vname;
897+
STR ", ";
898+
offset_to_pretty offset;
899+
STR ")"]
871900

872901

873902
let get_global_vars_in_exp (env:cfundeclarations_int) (e:exp) =

CodeHawk/CHC/cchpre/cCHPreTypes.mli

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -863,11 +863,11 @@ type po_predicate_t =
863863
| PLocallyInitialized of varinfo * lval
864864
(** lval is initialized locally or distinct from the region pointed to by varinfo *)
865865

866-
| POutputParameterInitialized of varinfo
867-
(** the memory region pointed to by varinfo is fully initialized *)
866+
| POutputParameterInitialized of varinfo * offset
867+
(** the memory region pointed to by varinfo with [offset] is fully initialized *)
868868

869-
| POutputParameterUnaltered of varinfo
870-
(** the memory region pointed to by varinfo is unaltered *)
869+
| POutputParameterUnaltered of varinfo * offset
870+
(** the memory region pointed to by varinfo with [offset] is unaltered *)
871871

872872

873873
type violation_severity_t =
@@ -1469,6 +1469,11 @@ class type user_assumptions_int =
14691469

14701470
(** {1 Proof scaffolding}*)
14711471

1472+
type analysis_info_t =
1473+
| UndefinedBehaviorInfo
1474+
| OutputParameterInfo of varinfo list
1475+
1476+
14721477
class type proof_scaffolding_int =
14731478
object
14741479

@@ -1478,6 +1483,9 @@ class type proof_scaffolding_int =
14781483
method retrieve_contract_preconditions:
14791484
cfundeclarations_int -> string -> unit
14801485

1486+
method set_analysis_info: string -> analysis_info_t -> unit
1487+
method get_analysis_info: string -> analysis_info_t
1488+
14811489
method get_function_api: string -> function_api_int
14821490

14831491
method get_ppo_manager: string -> ppo_manager_int

CodeHawk/CHC/cchpre/cCHPredicateDictionary.ml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,8 +147,10 @@ object (self)
147147
| PBuffer (e1, e2) -> (tags, [cd#index_exp e1; cd#index_exp e2])
148148
| PRevBuffer (e1, e2) -> (tags, [cd#index_exp e1; cd#index_exp e2])
149149
| PDistinctRegion (e, i) -> (tags, [cd#index_exp e; i])
150-
| POutputParameterInitialized vinfo -> (tags, [cdecls#index_varinfo vinfo])
151-
| POutputParameterUnaltered vinfo -> (tags, [cdecls#index_varinfo vinfo])
150+
| POutputParameterInitialized (vinfo, offset) ->
151+
(tags, [cdecls#index_varinfo vinfo; cd#index_offset offset])
152+
| POutputParameterUnaltered (vinfo, offset) ->
153+
(tags, [cdecls#index_varinfo vinfo; cd#index_offset offset])
152154
in
153155
po_predicate_table#add key
154156

@@ -265,8 +267,12 @@ object (self)
265267
| "rb" -> PRevBuffer (cd#get_exp (a 0), cd#get_exp (a 1))
266268
| "nm" -> PNewMemory (cd#get_exp (a 0))
267269
| "dr" -> PDistinctRegion (cd#get_exp (a 0), a 1)
268-
| "opi" -> POutputParameterInitialized (cdecls#get_varinfo (a 0))
269-
| "opu" -> POutputParameterUnaltered (cdecls#get_varinfo (a 0))
270+
| "opi" ->
271+
POutputParameterInitialized
272+
(cdecls#get_varinfo (a 0), cd#get_offset (a 1))
273+
| "opu" ->
274+
POutputParameterUnaltered
275+
(cdecls#get_varinfo (a 0), cd#get_offset (a 1))
270276
| s -> raise_tag_error name s po_predicate_mcts#tags
271277

272278

0 commit comments

Comments
 (0)