Skip to content

Commit c9e1cd2

Browse files
committed
CHC: add locations to diagnostic messages
1 parent 25658ef commit c9e1cd2

File tree

2 files changed

+121
-43
lines changed

2 files changed

+121
-43
lines changed

CodeHawk/CHC/cchanalyze/cCHAnalysisTypes.mli

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -440,26 +440,45 @@ class type po_query_int =
440440
(** [record_safe_result deps expl] adds the assumptions in [deps] to the
441441
function api or global environment with PO as a dependent, sets the
442442
status of PO to safe (Green), and records the dependencies and
443-
explanation [expl] in PO.*)
444-
method record_safe_result: dependencies_t -> string -> unit
443+
explanation [expl] in PO. Optionally a [site] can be added that
444+
records the location in the ocaml code that provided the decision
445+
*)
446+
method record_safe_result:
447+
?site:(string * int * string) option
448+
-> dependencies_t
449+
-> string
450+
-> unit
445451

446452
(** [record_violation_result deps expl] sets the status of PO to violated
447453
(Red), and records the dependencies [deps] and explanation [expl]
448-
in PO.*)
449-
method record_violation_result: dependencies_t -> string -> unit
454+
in PO. Optionally a [site] can be added that records the location in
455+
the ocaml code that provided the decision
456+
*)
457+
method record_violation_result:
458+
?site:(string * int * string) option
459+
-> dependencies_t
460+
-> string
461+
-> unit
450462

451463
(** [delegate_to_api isfile isglobal ppred invindices] checks if the local
452464
predicate [ppred] can be converted to an external (api) predicate. If so,
453465
it converts [ppred] to an api predicate and creates a dependency on this
454466
api assumption, justified by the invariants indicated by [invindices].
455467
It sets the status to safe (Green) and adds an explanation stating that the
456468
PO has been delegated to the api. In this case [true] is returned.
469+
Optionally a [site] can be added that records the location in the ocaml
470+
code that provided the decision.
457471
458472
If [ppred] cannot be converted to an api predicate a diagnostic is set
459473
to this effect, and [false] is returned.
460474
*)
461475
method delegate_to_api:
462-
?isfile:bool -> ?isglobal:bool -> po_predicate_t -> int list -> bool
476+
?site:(string * int * string) option
477+
-> ?isfile:bool
478+
-> ?isglobal:bool
479+
-> po_predicate_t
480+
-> int list
481+
-> bool
463482

464483
(** {1 Make requests} *)
465484

@@ -479,47 +498,75 @@ class type po_query_int =
479498
(** {1 Set diagnostics} *)
480499

481500
(** [set_diagnostic msg] adds message [msg] to the list of general diagnostics
482-
of PO.*)
483-
method set_diagnostic: string -> unit
501+
of PO. Optionally a [site] can be added that records the location of the
502+
generation of the diagnostic message.*)
503+
method set_diagnostic: ?site: (string * int * string) option -> string -> unit
484504

485505
(** [set_key_diagnostic key msg] adds message [msg] as a key diagnostic to
486-
PO with key [key].
506+
PO with key [key] Optionally a [site] can be added that records the
507+
location of the generation of the diagnostic message..
487508
488509
A key diagnostic is a diagnostic that refers to a particular as yet
489510
unsolved challenge in the analysis such as the analysis of
490511
null-termination that prevents the proof obligation to be discharged.
491512
*)
492-
method set_key_diagnostic: string -> string -> unit
513+
method set_key_diagnostic:
514+
?site:(string * int * string) option -> string -> string -> unit
493515

494516
(** [set_ref_diagnostic fname] adds a key diagnostic to PO for a challenge
495-
in the analysis associated with the function summary for [fname].*)
496-
method set_ref_diagnostic: string -> unit
517+
in the analysis associated with the function summary for [fname].
518+
Optionally a [site] can be added that records the location of the
519+
generation of the diagnoatic message.
520+
*)
521+
method set_ref_diagnostic:
522+
?site:(string * int * string) option -> string -> unit
497523

498524
(** [set_diagnostic_arg argindex msg] adds a diagnostic message [msg] to
499-
PO associated with the PO argument with (1-based) index [argindex].*)
500-
method set_diagnostic_arg: int -> string -> unit
525+
PO associated with the PO argument with (1-based) index [argindex].
526+
Optionally a [site] can be added that records the location of the
527+
generation of the diagnostic message.
528+
*)
529+
method set_diagnostic_arg:
530+
?site:(string * int * string) option -> int -> string -> unit
501531

502532
(** [set_exp_diagnostic lb ub exp msg] adds a diagnostic msg [msg] to PO for
503533
the expression [exp] prefixed by lb-exp if [lb], ub-exp if [ub] or exp
504-
if neither of these is true.*)
505-
method set_exp_diagnostic: ?lb:bool -> ?ub:bool -> exp -> string -> unit
534+
if neither of these is true. Optionally a [site] can be added that records
535+
the location of the generation of the diagnostic message.
536+
*)
537+
method set_exp_diagnostic:
538+
?site:(string * int * string) option
539+
-> ?lb:bool
540+
-> ?ub:bool
541+
-> exp
542+
-> string
543+
-> unit
506544

507545
(** [set_diagnostic_invariants argindex] adds the invariants associated with
508546
the argument with (1-based) index [argindex] to the diagnostic invariant
509547
table for [argindex].*)
510548
method set_diagnostic_invariants: int -> unit
511549

512550
(** Adds a message to PO that contains all calls that separate this PO from
513-
an entry symbol.*)
514-
method set_diagnostic_call_invariants: unit
551+
an entry symbol. Optionally a [site] can be added that records the
552+
location of the generation of the diagnostic message.
553+
*)
554+
method set_diagnostic_call_invariants:
555+
?site:(string * int * string) option -> unit -> unit
515556

516557
(** [set_vinfo_diagnostic vinfo] adds a diagnostic message to PO that lists
517-
all values that variable [vinfo] may have in this PO.*)
518-
method set_vinfo_diagnostic_invariants: varinfo -> unit
558+
all values that variable [vinfo] may have in this PO. Optionally a [site]
559+
can be added that records the location of the generation of the diagnostic
560+
message.
561+
*)
562+
method set_vinfo_diagnostic_invariants:
563+
?site:(string * int * string) option -> varinfo -> unit
519564

520-
method set_all_diagnostic_invariants: unit
565+
method set_all_diagnostic_invariants:
566+
?site:(string * int * string) option -> unit -> unit
521567

522-
method set_init_vinfo_mem_diagnostic_invariants: varinfo -> offset -> unit
568+
method set_init_vinfo_mem_diagnostic_invariants:
569+
?site:(string * int * string) option -> varinfo -> offset -> unit
523570

524571
method add_local_spo: location -> program_context_int -> po_predicate_t -> unit
525572

CodeHawk/CHC/cchanalyze/cCHPOQuery.ml

Lines changed: 53 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -285,51 +285,68 @@ object (self)
285285
None
286286

287287
method private record_proof_result
288+
?(site: (string * int * string) option = None)
288289
(status:po_status_t)
289290
(deps:dependencies_t)
290291
(expl:string) =
291292
begin
292293
po#set_status status;
293294
po#set_dependencies deps;
294-
po#set_explanation expl;
295+
po#set_explanation ~site expl;
295296
po#set_resolution_timestamp (current_time_to_string ())
296297
end
297298

298-
method set_diagnostic (msg: string) = po#add_diagnostic_msg msg
299+
method set_diagnostic
300+
?(site: (string * int * string) option = None)
301+
(msg: string) =
302+
po#add_diagnostic_msg ~site msg
299303

300-
method set_key_diagnostic (key: string) (msg: string) =
301-
po#add_diagnostic_key_msg key msg
304+
method set_key_diagnostic
305+
?(site: (string * int * string) option = None)
306+
(key: string)
307+
(msg: string) =
308+
po#add_diagnostic_key_msg ~site key msg
302309

303-
method set_ref_diagnostic (fname: string) =
310+
method set_ref_diagnostic
311+
?(site: (string * int * string) option = None) (fname: string) =
304312
match self#get_summary fname with
305313
| Some s ->
306314
begin
307315
match s.fs_domainref with
308316
| Some (ref, desc) ->
309-
po#add_diagnostic_key_msg ("DomainRef:" ^ ref ^ ":" ^ fname) desc
317+
po#add_diagnostic_key_msg ~site ("DomainRef:" ^ ref ^ ":" ^ fname) desc
310318
| _ -> ()
311319
end
312320
| _ -> ()
313321

314-
method set_diagnostic_arg (index: int) (txt: string) =
322+
method set_diagnostic_arg
323+
?(site: (string * int * string) option = None)
324+
(index: int)
325+
(txt: string) =
315326
let txt = "[" ^ (string_of_int) index ^ "]:" ^ txt in
316-
po#add_diagnostic_arg_msg index txt
327+
po#add_diagnostic_arg_msg ~site index txt
317328

318-
method set_exp_diagnostic ?(lb=false) ?(ub=false) (e:exp) (s:string) =
329+
method set_exp_diagnostic
330+
?(site: (string * int * string) option = None)
331+
?(lb=false)
332+
?(ub=false)
333+
(e:exp)
334+
(s:string) =
319335
match e with
320336
| Const (CInt _) -> ()
321337
| _ ->
322338
let prefix =
323339
if lb then "lb-exp" else if ub then "ub-exp" else "exp" in
324-
self#set_diagnostic ("[" ^ prefix ^ ":" ^ (e2s e) ^ "]: " ^ s)
340+
self#set_diagnostic ~site ("[" ^ prefix ^ ":" ^ (e2s e) ^ "]: " ^ s)
325341

326342
method set_diagnostic_invariants (index:int) =
327343
let invs = List.map (fun inv -> inv#index) (self#get_invariants index) in
328344
match invs with
329345
| [] -> ()
330346
| _ -> po#set_diagnostic_invariants index invs
331347

332-
method set_diagnostic_call_invariants =
348+
method set_diagnostic_call_invariants
349+
?(site: (string * int * string) option = None) () =
333350
let callinvs = self#get_call_invariants in
334351
let entrysym = env#get_p_entry_sym in
335352
List.iter (fun inv ->
@@ -338,22 +355,25 @@ object (self)
338355
begin
339356
match l with
340357
| [s] when s#equal entrysym ->
341-
self#set_diagnostic ("[" ^ v#getName#getBaseName ^ ":calls]:none")
358+
self#set_diagnostic
359+
~site ("[" ^ v#getName#getBaseName ^ ":calls]:none")
342360
| _ ->
343361
let lst =
344362
List.fold_left (fun acc s ->
345363
if s#equal entrysym then
346364
acc
347365
else
348366
acc ^ "; " ^ s#getBaseName) "" l in
349-
self#set_diagnostic ("[" ^ v#getName#getBaseName ^ ":calls]" ^ lst)
367+
self#set_diagnostic
368+
~site("[" ^ v#getName#getBaseName ^ ":calls]" ^ lst)
350369
end
351370
| _ -> ()) callinvs
352371

353-
method set_all_diagnostic_invariants =
372+
method set_all_diagnostic_invariants
373+
?(site: (string * int * string) option = None) () =
354374
let locinv = invio#get_location_invariant cfgcontext in
355375
let invs = locinv#get_invariants in
356-
List.iter (fun inv -> po#add_diagnostic_msg (p2s (inv#toPretty))) invs
376+
List.iter (fun inv -> po#add_diagnostic_msg ~site (p2s (inv#toPretty))) invs
357377

358378
method get_init_vinfo_mem_invariants
359379
(vinfo: varinfo) (offset: offset): invariant_int list =
@@ -377,6 +397,7 @@ object (self)
377397
| _ -> acc) [] (invio#get_location_invariant cfgcontext)#get_invariants
378398

379399
method set_init_vinfo_mem_diagnostic_invariants
400+
?(site: (string * int * string) option = None)
380401
(vinfo: varinfo) (offset: offset) =
381402
let numv = self#env#mk_program_var vinfo NoOffset NUM_VAR_TYPE in
382403
let ctxtinvs = (invio#get_location_invariant cfgcontext)#get_invariants in
@@ -398,12 +419,14 @@ object (self)
398419
else
399420
acc
400421
| _ -> acc) [] ctxtinvs in
401-
List.iter (fun inv -> po#add_diagnostic_msg (p2s (inv#toPretty))) invs
422+
List.iter (fun inv -> po#add_diagnostic_msg ~site (p2s (inv#toPretty))) invs
402423

403-
method set_vinfo_diagnostic_invariants (vinfo:varinfo) =
424+
method set_vinfo_diagnostic_invariants
425+
?(site: (string * int * string) option = None) (vinfo:varinfo) =
404426
let vinfovalues = self#get_vinfo_offset_values vinfo in
405427
List.iter (fun (inv, offset) ->
406428
po#add_diagnostic_msg
429+
~site
407430
("["
408431
^ vinfo.vname
409432
^ "]: "
@@ -416,7 +439,10 @@ object (self)
416439
method private record_unevaluated (x:xpr_t) =
417440
fApi#add_unevaluated po#get_predicate (xd#index_xpr x)
418441

419-
method record_safe_result (deps:dependencies_t) (expl:string) =
442+
method record_safe_result
443+
?(site: (string * int * string) option = None)
444+
(deps: dependencies_t)
445+
(expl: string) =
420446
let _ = match deps with
421447
| DEnvC (_, assumptions) ->
422448
let (ppos, spos) = self#get_ppos_spos in
@@ -434,12 +460,16 @@ object (self)
434460
(fApi#add_api_assumption ~isglobal:true ~ppos ~spos pred)
435461
) assumptions
436462
| _ -> () in
437-
self#record_proof_result Green deps expl
463+
self#record_proof_result ~site Green deps expl
438464

439-
method record_violation_result (deps:dependencies_t) (expl:string) =
440-
self#record_proof_result Red deps expl
465+
method record_violation_result
466+
?(site: (string * int * string) option = None)
467+
(deps:dependencies_t)
468+
(expl:string) =
469+
self#record_proof_result ~site Red deps expl
441470

442471
method delegate_to_api
472+
?(site: (string * int * string) option = None)
443473
?(isfile=false)
444474
?(isglobal=false)
445475
(pred:po_predicate_t)
@@ -454,12 +484,13 @@ object (self)
454484
^ (p2s (po_predicate_to_pretty apred))
455485
^ " delegated to api" in
456486
begin
457-
self#record_proof_result Green deps expl;
487+
self#record_proof_result ~site Green deps expl;
458488
true
459489
end
460490
| _ ->
461491
begin
462492
self#set_diagnostic
493+
~site
463494
("condition " ^ (p2s (po_predicate_to_pretty pred)) ^ " not delegated");
464495
false
465496
end

0 commit comments

Comments
 (0)