[inferbo] Only callee formals are needed

Reviewed By: skcho

Differential Revision: D13865391

fbshipit-source-id: bfe3b4d13
master
Mehdi Bouaziz 6 years ago committed by Facebook Github Bot
parent 1765b66916
commit e4bb3c9d68

@ -55,9 +55,8 @@ module TransferFunctions = struct
type nonrec extras = extras type nonrec extras = extras
let instantiate_mem_reachable (ret_id, _) callee_pdesc callee_pname ~callee_exit_mem let instantiate_mem_reachable (ret_id, _) callee_formals callee_pname ~callee_exit_mem
({Dom.eval_locpath} as eval_sym_trace) mem location = ({Dom.eval_locpath} as eval_sym_trace) mem location =
let formals = Procdesc.get_pvar_formals callee_pdesc in
let copy_reachable_locs_from locs mem = let copy_reachable_locs_from locs mem =
let copy loc acc = let copy loc acc =
Option.value_map (Dom.Mem.find_opt loc callee_exit_mem) ~default:acc ~f:(fun v -> Option.value_map (Dom.Mem.find_opt loc callee_exit_mem) ~default:acc ~f:(fun v ->
@ -65,7 +64,7 @@ module TransferFunctions = struct
let v = Dom.Val.subst v eval_sym_trace location in let v = Dom.Val.subst v eval_sym_trace location in
PowLoc.fold (fun loc acc -> Dom.Mem.add_heap loc v acc) locs acc ) PowLoc.fold (fun loc acc -> Dom.Mem.add_heap loc v acc) locs acc )
in in
let reachable_locs = Dom.Mem.get_reachable_locs_from formals locs callee_exit_mem in let reachable_locs = Dom.Mem.get_reachable_locs_from callee_formals locs callee_exit_mem in
PowLoc.fold copy reachable_locs mem PowLoc.fold copy reachable_locs mem
in in
let instantiate_ret_alias mem = let instantiate_ret_alias mem =
@ -89,7 +88,7 @@ module TransferFunctions = struct
let ret_var = Loc.of_var (Var.of_id ret_id) in let ret_var = Loc.of_var (Var.of_id ret_id) in
let ret_val = Dom.Mem.find (Loc.of_pvar (Pvar.get_ret_pvar callee_pname)) callee_exit_mem in let ret_val = Dom.Mem.find (Loc.of_pvar (Pvar.get_ret_pvar callee_pname)) callee_exit_mem in
let formal_locs = let formal_locs =
List.fold formals ~init:PowLoc.bot ~f:(fun acc (formal, _) -> List.fold callee_formals ~init:PowLoc.bot ~f:(fun acc (formal, _) ->
let v = Dom.Mem.find (Loc.of_pvar formal) callee_exit_mem in let v = Dom.Mem.find (Loc.of_pvar formal) callee_exit_mem in
PowLoc.join acc (Dom.Val.get_all_locs v) ) PowLoc.join acc (Dom.Val.get_all_locs v) )
in in
@ -116,23 +115,23 @@ module TransferFunctions = struct
Tenv.t Tenv.t
-> Typ.IntegerWidths.t -> Typ.IntegerWidths.t
-> Ident.t * Typ.t -> Ident.t * Typ.t
-> Procdesc.t -> (Pvar.t * Typ.t) list
-> Typ.Procname.t -> Typ.Procname.t
-> (Exp.t * Typ.t) list -> (Exp.t * Typ.t) list
-> Dom.Mem.t -> Dom.Mem.t
-> BufferOverrunAnalysisSummary.t -> BufferOverrunAnalysisSummary.t
-> Location.t -> Location.t
-> Dom.Mem.t = -> Dom.Mem.t =
fun tenv integer_type_widths ret callee_pdesc callee_pname params caller_mem callee_exit_mem fun tenv integer_type_widths ret callee_formals callee_pname params caller_mem callee_exit_mem
location -> location ->
let rel_subst_map = let rel_subst_map =
Sem.get_subst_map tenv integer_type_widths callee_pdesc params caller_mem callee_exit_mem Sem.get_subst_map tenv integer_type_widths callee_formals params caller_mem callee_exit_mem
in in
let eval_sym_trace = let eval_sym_trace =
Sem.mk_eval_sym_trace integer_type_widths callee_pdesc params caller_mem ~strict:false Sem.mk_eval_sym_trace integer_type_widths callee_formals params caller_mem ~strict:false
in in
let caller_mem = let caller_mem =
instantiate_mem_reachable ret callee_pdesc callee_pname ~callee_exit_mem eval_sym_trace instantiate_mem_reachable ret callee_formals callee_pname ~callee_exit_mem eval_sym_trace
caller_mem location caller_mem location
|> forget_ret_relation ret callee_pname |> forget_ret_relation ret callee_pname
in in
@ -233,11 +232,13 @@ module TransferFunctions = struct
Ondemand.analyze_proc_name ~caller_pdesc:pdesc callee_pname Ondemand.analyze_proc_name ~caller_pdesc:pdesc callee_pname
|> Option.bind ~f:(fun callee_summary -> |> Option.bind ~f:(fun callee_summary ->
Payload.of_summary callee_summary Payload.of_summary callee_summary
|> Option.map ~f:(fun payload -> (payload, Summary.get_proc_desc callee_summary)) |> Option.map ~f:(fun payload ->
( payload
, Summary.get_proc_desc callee_summary |> Procdesc.get_pvar_formals ) )
) )
with with
| Some (callee_exit_mem, callee_pdesc) -> | Some (callee_exit_mem, callee_formals) ->
instantiate_mem tenv integer_type_widths ret callee_pdesc callee_pname params mem instantiate_mem tenv integer_type_widths ret callee_formals callee_pname params mem
callee_exit_mem location callee_exit_mem location
| None -> | None ->
(* This may happen for procedures with a biabduction model too. *) (* This may happen for procedures with a biabduction model too. *)

@ -243,21 +243,24 @@ let rec check_expr_for_integer_overflow integer_type_widths exp location mem con
let instantiate_cond : let instantiate_cond :
Tenv.t Tenv.t
-> Typ.IntegerWidths.t -> Typ.IntegerWidths.t
-> Procdesc.t -> Typ.Procname.t
-> (Pvar.t * Typ.t) list
-> (Exp.t * Typ.t) list -> (Exp.t * Typ.t) list
-> Dom.Mem.t -> Dom.Mem.t
-> BufferOverrunAnalysisSummary.t -> BufferOverrunAnalysisSummary.t
-> BufferOverrunCheckerSummary.t -> BufferOverrunCheckerSummary.t
-> Location.t -> Location.t
-> PO.ConditionSet.checked_t = -> PO.ConditionSet.checked_t =
fun tenv integer_type_widths callee_pdesc params caller_mem callee_exit_mem callee_cond location -> fun tenv integer_type_widths callee_pname callee_formals params caller_mem callee_exit_mem
callee_cond location ->
let rel_subst_map = let rel_subst_map =
Sem.get_subst_map tenv integer_type_widths callee_pdesc params caller_mem callee_exit_mem Sem.get_subst_map tenv integer_type_widths callee_formals params caller_mem callee_exit_mem
in in
let pname = Procdesc.get_proc_name callee_pdesc in
let caller_rel = Dom.Mem.get_relation caller_mem in let caller_rel = Dom.Mem.get_relation caller_mem in
let eval_sym_trace = Sem.mk_eval_sym_trace integer_type_widths callee_pdesc params caller_mem in let eval_sym_trace =
PO.ConditionSet.subst callee_cond eval_sym_trace rel_subst_map caller_rel pname location Sem.mk_eval_sym_trace integer_type_widths callee_formals params caller_mem
in
PO.ConditionSet.subst callee_cond eval_sym_trace rel_subst_map caller_rel callee_pname location
let check_instr : let check_instr :
@ -301,11 +304,13 @@ let check_instr :
let checker_payload = Payload.of_summary callee_summary in let checker_payload = Payload.of_summary callee_summary in
Option.map2 analysis_payload checker_payload Option.map2 analysis_payload checker_payload
~f:(fun analysis_payload checker_payload -> ~f:(fun analysis_payload checker_payload ->
(analysis_payload, checker_payload, Summary.get_proc_desc callee_summary) ) ) ( analysis_payload
, checker_payload
, Summary.get_proc_desc callee_summary |> Procdesc.get_pvar_formals ) ) )
with with
| Some (callee_mem, callee_condset, callee_pdesc) -> | Some (callee_mem, callee_condset, callee_formals) ->
instantiate_cond tenv integer_type_widths callee_pdesc params mem callee_mem instantiate_cond tenv integer_type_widths callee_pname callee_formals params mem
callee_condset location callee_mem callee_condset location
|> PO.ConditionSet.join cond_set |> PO.ConditionSet.join cond_set
| None -> | None ->
(* unknown call / no inferbo payload *) cond_set ) ) (* unknown call / no inferbo payload *) cond_set ) )

@ -407,11 +407,10 @@ let eval_sympath ~strict params sympath mem =
- non-strict mode (which is used by default): it returns the unknown location. - non-strict mode (which is used by default): it returns the unknown location.
- strict mode (which is used only in the substitution of condition of proof obligation): it - strict mode (which is used only in the substitution of condition of proof obligation): it
returns the bottom location. *) returns the bottom location. *)
let mk_eval_sym_trace integer_type_widths callee_pdesc actual_exps caller_mem = let mk_eval_sym_trace integer_type_widths callee_formals actual_exps caller_mem =
let params = let params =
let formals = Procdesc.get_pvar_formals callee_pdesc in
let actuals = List.map ~f:(fun (a, _) -> eval integer_type_widths a caller_mem) actual_exps in let actuals = List.map ~f:(fun (a, _) -> eval integer_type_widths a caller_mem) actual_exps in
ParamBindings.make formals actuals ParamBindings.make callee_formals actuals
in in
let eval_sym s bound_end = let eval_sym s bound_end =
let sympath = Symb.Symbol.path s in let sympath = Symb.Symbol.path s in
@ -729,12 +728,12 @@ let rec list_fold2_def :
let get_subst_map : let get_subst_map :
Tenv.t Tenv.t
-> Typ.IntegerWidths.t -> Typ.IntegerWidths.t
-> Procdesc.t -> (Pvar.t * Typ.t) list
-> (Exp.t * 'a) list -> (Exp.t * 'a) list
-> Mem.t -> Mem.t
-> _ Mem.t0 -> _ Mem.t0
-> Relation.SubstMap.t = -> Relation.SubstMap.t =
fun tenv integer_type_widths callee_pdesc params caller_mem callee_exit_mem -> fun tenv integer_type_widths callee_formals params caller_mem callee_exit_mem ->
let add_pair (formal, typ) (actual, actual_exp) rel_l = let add_pair (formal, typ) (actual, actual_exp) rel_l =
let callee_v = Mem.find (Loc.of_pvar formal) callee_exit_mem in let callee_v = Mem.find (Loc.of_pvar formal) callee_exit_mem in
let new_rel_matching = let new_rel_matching =
@ -743,11 +742,10 @@ let get_subst_map :
in in
List.rev_append new_rel_matching rel_l List.rev_append new_rel_matching rel_l
in in
let formals = Procdesc.get_pvar_formals callee_pdesc in
let actuals = let actuals =
List.map ~f:(fun (a, _) -> (eval integer_type_widths a caller_mem, Some a)) params List.map ~f:(fun (a, _) -> (eval integer_type_widths a caller_mem, Some a)) params
in in
let rel_pairs = let rel_pairs =
list_fold2_def ~default:(Val.Itv.top, None) ~f:add_pair formals actuals ~init:[] list_fold2_def ~default:(Val.Itv.top, None) ~f:add_pair callee_formals actuals ~init:[]
in in
subst_map_of_rel_pairs rel_pairs subst_map_of_rel_pairs rel_pairs

@ -41,8 +41,9 @@ let instantiate_cost integer_type_widths ~inferbo_caller_mem ~callee_pname ~para
"Can't instantiate symbolic cost %a from call to %a (can't get procdesc)" BasicCost.pp "Can't instantiate symbolic cost %a from call to %a (can't get procdesc)" BasicCost.pp
callee_cost Typ.Procname.pp callee_pname callee_cost Typ.Procname.pp callee_pname
| Some callee_pdesc -> | Some callee_pdesc ->
let callee_formals = Procdesc.get_pvar_formals callee_pdesc in
let eval_sym = let eval_sym =
BufferOverrunSemantics.mk_eval_sym integer_type_widths callee_pdesc params BufferOverrunSemantics.mk_eval_sym integer_type_widths callee_formals params
inferbo_caller_mem inferbo_caller_mem
in in
BasicCost.subst callee_cost eval_sym BasicCost.subst callee_cost eval_sym

Loading…
Cancel
Save