diff --git a/infer/src/bufferoverrun/bufferOverrunChecker.ml b/infer/src/bufferoverrun/bufferOverrunChecker.ml index 55c20f15b..1cb43db38 100644 --- a/infer/src/bufferoverrun/bufferOverrunChecker.ml +++ b/infer/src/bufferoverrun/bufferOverrunChecker.ml @@ -600,6 +600,8 @@ module Report = struct let forget_locs = PO.ConditionSet.forget_locs + + let for_summary = PO.ConditionSet.for_summary end let extract_pre = Analyzer.extract_pre @@ -609,7 +611,7 @@ let extract_post = Analyzer.extract_post let print_summary : Typ.Procname.t -> Dom.Summary.t -> unit = fun proc_name s -> L.(debug BufferOverrun Medium) - "@\n@[Summary of %a:@,%a@]@." Typ.Procname.pp proc_name Dom.Summary.pp_summary s + "@\n@[Summary of %a:@,%a@]@." Typ.Procname.pp proc_name Dom.Summary.pp s let get_local_decls proc_desc = @@ -637,7 +639,7 @@ let compute_invariant_map_and_check : Callbacks.proc_callback_args -> invariant_ in let cond_set = Report.check_proc summary proc_desc tenv symbol_table cfg inv_map - |> Report.report_errors summary |> Report.forget_locs locals + |> Report.report_errors summary |> Report.forget_locs locals |> Report.for_summary in let summary = match exit_mem with diff --git a/infer/src/bufferoverrun/bufferOverrunDomain.ml b/infer/src/bufferoverrun/bufferOverrunDomain.ml index c582bbac2..6b1af0175 100644 --- a/infer/src/bufferoverrun/bufferOverrunDomain.ml +++ b/infer/src/bufferoverrun/bufferOverrunDomain.ml @@ -289,10 +289,6 @@ module Val = struct {x with traces} - let pp_summary : F.formatter -> t -> unit = - fun fmt x -> F.fprintf fmt "(%a, %a)" Itv.pp x.itv ArrayBlk.pp x.arrayblk - - let set_array_size : Itv.t -> t -> t = fun size v -> {v with arrayblk= ArrayBlk.set_size size v.arrayblk} @@ -321,12 +317,6 @@ module MemPure = struct let bot = empty - let get_return : astate -> Val.t = - fun mem -> - let mem = filter (fun l _ -> Loc.is_return l) mem in - if is_empty mem then Val.bot else snd (choose mem) - - let range : filter_loc:(Loc.t -> bool) -> astate -> Itv.NonNegativePolynomial.astate = fun ~filter_loc mem -> fold @@ -745,8 +735,6 @@ module MemReach = struct let weak_update locs v m = transform_mem ~f:(fun v' -> Val.join v' v) locs m - let get_return : t -> Val.t = fun m -> MemPure.get_return m.mem_pure - let update_mem : PowLoc.t -> Val.t -> t -> t = fun ploc v s -> if can_strong_update ploc then strong_update ploc v s @@ -936,8 +924,6 @@ module Mem = struct let weak_update : PowLoc.t -> Val.t -> t -> t = fun p v -> f_lift (MemReach.weak_update p v) - let get_return : t -> Val.t = f_lift_default ~default:Val.bot MemReach.get_return - let get_reachable_locs_from : PowLoc.t -> t -> PowLoc.t = fun locs -> f_lift_default ~default:PowLoc.empty (MemReach.get_reachable_locs_from locs) @@ -997,32 +983,16 @@ module Mem = struct end module Summary = struct - type t = Itv.SymbolTable.summary_t * Mem.t * PO.ConditionSet.t + type t = Itv.SymbolTable.summary_t * Mem.t * PO.ConditionSet.summary_t let get_symbol_table : t -> Itv.SymbolTable.summary_t = fst3 let get_output : t -> Mem.t = snd3 - let get_cond_set : t -> PO.ConditionSet.t = trd3 - - let get_return : t -> Val.t = fun s -> Mem.get_return (get_output s) - - let pp_symbol_map : F.formatter -> t -> unit = - fun fmt s -> Itv.SymbolTable.pp fmt (get_symbol_table s) - - - let pp_return : F.formatter -> t -> unit = - fun fmt s -> F.fprintf fmt "Return value: %a" Val.pp_summary (get_return s) - - - let pp_summary : F.formatter -> t -> unit = - fun fmt s -> - F.fprintf fmt "%a@,%a@,%a" pp_symbol_map s pp_return s PO.ConditionSet.pp_summary - (get_cond_set s) - + let get_cond_set : t -> PO.ConditionSet.summary_t = trd3 let pp : F.formatter -> t -> unit = fun fmt (symbol_table, exit_mem, condition_set) -> - F.fprintf fmt "%a@;%a@;%a" Itv.SymbolTable.pp symbol_table Mem.pp exit_mem PO.ConditionSet.pp - condition_set + F.fprintf fmt "%a@;%a@;%a" Itv.SymbolTable.pp symbol_table Mem.pp exit_mem + PO.ConditionSet.pp_summary condition_set end diff --git a/infer/src/bufferoverrun/bufferOverrunProofObligations.ml b/infer/src/bufferoverrun/bufferOverrunProofObligations.ml index 74e0a03b0..c83e9bfc3 100644 --- a/infer/src/bufferoverrun/bufferOverrunProofObligations.ml +++ b/infer/src/bufferoverrun/bufferOverrunProofObligations.ml @@ -357,27 +357,32 @@ module Condition = struct end module ConditionTrace = struct - type cond_trace = Intra | Inter of {call_site: Location.t; callee_pname: Typ.Procname.t} + type intra_cond_trace = Intra | Inter of {call_site: Location.t; callee_pname: Typ.Procname.t} [@@deriving compare] - type t = {cond_trace: cond_trace; issue_location: Location.t; val_traces: ValTraceSet.t} + type 'cond_trace t0 = + {cond_trace: 'cond_trace; issue_location: Location.t; val_traces: ValTraceSet.t} [@@deriving compare] - let pp_location : F.formatter -> t -> unit = - fun fmt ct -> Location.pp_file_pos fmt ct.issue_location + type t = intra_cond_trace t0 [@@deriving compare] + + type summary_t = unit t0 + + let pp_summary : F.formatter -> _ t0 -> unit = + fun fmt ct -> F.fprintf fmt "at %a" Location.pp_file_pos ct.issue_location let pp : F.formatter -> t -> unit = fun fmt ct -> - if Config.bo_debug <= 1 then F.fprintf fmt "at %a" pp_location ct - else + pp_summary fmt ct ; + if Config.bo_debug > 1 then match ct.cond_trace with | Inter {callee_pname; call_site} -> let pname = Typ.Procname.to_string callee_pname in - F.fprintf fmt "at %a by call to %s at %a (%a)" pp_location ct pname Location.pp_file_pos - call_site ValTraceSet.pp ct.val_traces + F.fprintf fmt " by call to %s at %a (%a)" pname Location.pp_file_pos call_site + ValTraceSet.pp ct.val_traces | Intra -> - F.fprintf fmt "%a (%a)" pp_location ct ValTraceSet.pp ct.val_traces + F.fprintf fmt " (%a)" ValTraceSet.pp ct.val_traces let pp_description : F.formatter -> t -> unit = @@ -409,8 +414,11 @@ module ConditionTrace = struct let has_unknown ct = ValTraceSet.has_unknown ct.val_traces - let check : t -> IssueType.t option = + let check : _ t0 -> IssueType.t option = fun ct -> if has_unknown ct then Some IssueType.buffer_overrun_u5 else None + + + let for_summary : _ t0 -> summary_t = fun ct -> {ct with cond_trace= ()} end module Reported = struct @@ -422,12 +430,17 @@ module Reported = struct end module ConditionWithTrace = struct - type t = {cond: Condition.t; trace: ConditionTrace.t; reported: Reported.t option} + type 'cond_trace t0 = + {cond: Condition.t; trace: 'cond_trace ConditionTrace.t0; reported: Reported.t option} let make cond trace = {cond; trace; reported= None} let pp fmt {cond; trace} = F.fprintf fmt "%a %a" Condition.pp cond ConditionTrace.pp trace + let pp_summary fmt {cond; trace} = + F.fprintf fmt "%a %a" Condition.pp cond ConditionTrace.pp_summary trace + + let have_similar_bounds {cond= cond1} {cond= cond2} = Condition.have_similar_bounds cond1 cond2 let xcompare ~lhs ~rhs = @@ -445,7 +458,7 @@ module ConditionWithTrace = struct L.(die InternalError) "Trying to substitute a non-symbolic condition %a from %a at %a. Why was it propagated in \ the first place?" - pp cwt Typ.Procname.pp callee_pname Location.pp call_site ; + pp_summary cwt Typ.Procname.pp callee_pname Location.pp call_site ; match Condition.subst bound_map rel_map caller_relation cwt.cond with | None -> None @@ -505,10 +518,17 @@ module ConditionWithTrace = struct let forget_locs locs cwt = {cwt with cond= Condition.forget_locs locs cwt.cond} + + let for_summary {cond; trace; reported} = + {cond; trace= ConditionTrace.for_summary trace; reported} end module ConditionSet = struct - type t = ConditionWithTrace.t list + type 'cond_trace t0 = 'cond_trace ConditionWithTrace.t0 list + + type t = ConditionTrace.intra_cond_trace t0 + + type summary_t = unit t0 (* invariant: join_one of one of the elements should return the original list *) @@ -593,12 +613,12 @@ module ConditionSet = struct let check_all ~report condset = List.filter_map condset ~f:(ConditionWithTrace.check ~report) - let pp_summary : F.formatter -> t -> unit = + let pp_summary : F.formatter -> _ t0 -> unit = fun fmt condset -> let pp_sep fmt () = F.fprintf fmt ", @," in F.fprintf fmt "@[Safety conditions:@," ; F.fprintf fmt "@[{ " ; - F.pp_print_list ~pp_sep ConditionWithTrace.pp fmt condset ; + F.pp_print_list ~pp_sep ConditionWithTrace.pp_summary fmt condset ; F.fprintf fmt " }@]" ; F.fprintf fmt "@]" @@ -611,8 +631,12 @@ module ConditionSet = struct condset - let forget_locs : AbsLoc.PowLoc.t -> t -> t = + let forget_locs : AbsLoc.PowLoc.t -> 'a t0 -> 'a t0 = fun locs x -> List.map x ~f:(ConditionWithTrace.forget_locs locs) + + + let for_summary : _ t0 -> summary_t = + fun condset -> List.map condset ~f:ConditionWithTrace.for_summary end let description cond trace = diff --git a/infer/src/bufferoverrun/bufferOverrunProofObligations.mli b/infer/src/bufferoverrun/bufferOverrunProofObligations.mli index 7fa356517..79a042916 100644 --- a/infer/src/bufferoverrun/bufferOverrunProofObligations.mli +++ b/infer/src/bufferoverrun/bufferOverrunProofObligations.mli @@ -26,11 +26,13 @@ end module ConditionSet : sig type t + type summary_t + val empty : t val pp : Format.formatter -> t -> unit - val pp_summary : Format.formatter -> t -> unit + val pp_summary : Format.formatter -> summary_t -> unit val add_array_access : Location.t -> idx:ItvPure.astate -> size:ItvPure.astate -> is_collection_add:bool @@ -42,12 +44,14 @@ module ConditionSet : sig val join : t -> t -> t val subst : - t -> Bounds.Bound.t bottom_lifted Symb.SymbolMap.t * ValTraceSet.t Symb.SymbolMap.t + summary_t -> Bounds.Bound.t bottom_lifted Symb.SymbolMap.t * ValTraceSet.t Symb.SymbolMap.t -> Relation.SubstMap.t -> Relation.astate -> Typ.Procname.t -> Location.t -> t val check_all : report:(Condition.t -> ConditionTrace.t -> IssueType.t -> unit) -> t -> t (** Check the conditions, call [report] on those that trigger an issue, returns those that needs to be propagated to callers. *) + val for_summary : t -> summary_t + val forget_locs : AbsLoc.PowLoc.t -> t -> t end