[quandary][perf] Always use the location of the pdesc in footprint sources

Reviewed By: mbouaziz

Differential Revision: D4721643

fbshipit-source-id: ce225c5
master
Sam Blackshear 8 years ago committed by Facebook Github Bot
parent 779ec1f0ad
commit 69fe80346c

@ -31,7 +31,7 @@ module type S = sig
val is_footprint : t -> bool
val make_footprint : AccessPath.t -> CallSite.t -> t
val make_footprint : AccessPath.t -> Procdesc.t -> t
val get_footprint_access_path: t -> AccessPath.t option
@ -76,8 +76,9 @@ module Make (Kind : Kind) = struct
let make kind site =
{ site; kind = Normal kind; }
let make_footprint ap site =
let make_footprint ap pdesc =
let kind = Footprint ap in
let site = CallSite.make (Procdesc.get_proc_name pdesc) (Procdesc.get_loc pdesc) in
{ site; kind; }
let get site tenv = match Kind.get (CallSite.pname site) tenv with
@ -91,12 +92,14 @@ module Make (Kind : Kind) = struct
name, typ, Option.map kind_opt ~f:(fun kind -> make kind site))
(Kind.get_tainted_formals pdesc tenv)
let with_callsite t callee_site =
{ t with site = callee_site; }
let pp fmt s =
F.fprintf fmt "%a(%a)" pp_kind s.kind CallSite.pp s.site
let with_callsite t callee_site =
if is_footprint t
then failwithf "Can't change the call site of footprint source %a" pp t;
{ t with site = callee_site; }
module Set = PrettyPrintable.MakePPSet(struct
type nonrec t = t
let compare = compare

@ -33,7 +33,7 @@ module type S = sig
val is_footprint : t -> bool
(** create a footprint source for the value read from the given access path. *)
val make_footprint : AccessPath.t -> CallSite.t -> t
val make_footprint : AccessPath.t -> Procdesc.t -> t
(** return Some(access path) if the current source is a footprint source, None otherwise *)
val get_footprint_access_path: t -> AccessPath.t option

@ -92,17 +92,15 @@ module Make (TaintSpecification : TaintSpec.S) = struct
with Not_found -> None
(* get the node associated with [access_path] in [access_tree] *)
let access_path_get_node access_path access_tree (proc_data : FormalMap.t ProcData.t) loc =
let access_path_get_node access_path access_tree (proc_data : FormalMap.t ProcData.t) =
match TaintDomain.get_node access_path access_tree with
| Some _ as node_opt ->
node_opt
| None ->
let make_footprint_trace footprint_ap =
let call_site =
CallSite.make (Procdesc.get_proc_name proc_data.ProcData.pdesc) loc in
let trace =
TraceDomain.of_source
(TraceDomain.Source.make_footprint footprint_ap call_site) in
(TraceDomain.Source.make_footprint footprint_ap proc_data.pdesc) in
Some (TaintDomain.make_normal_leaf trace) in
let root, _ = AccessPath.extract access_path in
match FormalMap.get_formal_index root proc_data.extras with
@ -114,13 +112,13 @@ module Make (TaintSpecification : TaintSpec.S) = struct
else None
(* get the trace associated with [access_path] in [access_tree]. *)
let access_path_get_trace access_path access_tree proc_data loc =
match access_path_get_node access_path access_tree proc_data loc with
let access_path_get_trace access_path access_tree proc_data =
match access_path_get_node access_path access_tree proc_data with
| Some (trace, _) -> trace
| None -> TraceDomain.empty
(* get the node associated with [exp] in [access_tree] *)
let exp_get_node ?(abstracted=false) exp typ { Domain.access_tree; id_map; } proc_data loc =
let exp_get_node ?(abstracted=false) exp typ { Domain.access_tree; id_map; } proc_data =
let f_resolve_id = resolve_id id_map in
match AccessPath.of_lhs_exp exp typ ~f_resolve_id with
| Some raw_access_path ->
@ -128,14 +126,14 @@ module Make (TaintSpecification : TaintSpec.S) = struct
if abstracted
then AccessPath.Abstracted raw_access_path
else AccessPath.Exact raw_access_path in
access_path_get_node access_path access_tree proc_data loc
access_path_get_node access_path access_tree proc_data
| None ->
(* can't make an access path from [exp] *)
None
let analyze_assignment lhs_access_path rhs_exp rhs_typ astate proc_data loc =
let analyze_assignment lhs_access_path rhs_exp rhs_typ astate proc_data =
let rhs_node =
match exp_get_node rhs_exp rhs_typ astate proc_data loc with
match exp_get_node rhs_exp rhs_typ astate proc_data with
| Some node -> node
| None -> TaintDomain.empty_node in
let access_tree = TaintDomain.add_node lhs_access_path rhs_node astate.Domain.access_tree in
@ -211,8 +209,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
then AccessPath.Abstracted actual_ap_raw
else AccessPath.Exact actual_ap_raw in
begin
match access_path_get_node
actual_ap access_tree_acc proc_data (CallSite.loc callee_site) with
match access_path_get_node actual_ap access_tree_acc proc_data with
| Some (actual_trace, _) ->
let actual_trace' = TraceDomain.add_sink sink_param.sink actual_trace in
report_trace actual_trace' callee_site proc_data;
@ -232,7 +229,6 @@ module Make (TaintSpecification : TaintSpec.S) = struct
(astate_in : Domain.astate)
(proc_data : FormalMap.t ProcData.t)
callee_site =
let callee_loc = CallSite.loc callee_site in
let caller_access_tree = astate_in.access_tree in
let get_caller_ap formal_ap =
@ -273,8 +269,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
let get_caller_ap_node ap access_tree =
match get_caller_ap ap with
| Some caller_ap ->
let caller_node_opt =
access_path_get_node caller_ap access_tree proc_data callee_loc in
let caller_node_opt = access_path_get_node caller_ap access_tree proc_data in
let caller_node = match caller_node_opt with
| Some caller_node -> caller_node | None -> TaintDomain.empty_node in
caller_ap, caller_node
@ -339,7 +334,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
Location.pp loc in
let astate' =
analyze_assignment
(AccessPath.Exact lhs_access_path) rhs_exp lhs_typ astate proc_data loc in
(AccessPath.Exact lhs_access_path) rhs_exp lhs_typ astate proc_data in
begin
(* direct `exp = id` assignments are treated specially; we update the id map too. this
is so future reads of `exp` will get the subtree associated with `id` (needed to
@ -375,12 +370,11 @@ module Make (TaintSpecification : TaintSpec.S) = struct
let handle_unknown_call callee_pname astate =
let exp_join_traces trace_acc (exp, typ) =
match exp_get_node ~abstracted:true exp typ astate proc_data callee_loc with
match exp_get_node ~abstracted:true exp typ astate proc_data with
| Some (trace, _) -> TraceDomain.join trace trace_acc
| None -> trace_acc in
let propagate_to_access_path access_path actuals (astate : Domain.astate) =
let initial_trace =
access_path_get_trace access_path astate.access_tree proc_data callee_loc in
let initial_trace = access_path_get_trace access_path astate.access_tree proc_data in
let trace_with_propagation =
List.fold ~f:exp_join_traces ~init:initial_trace actuals in
let access_tree =

@ -114,7 +114,11 @@ let tests =
let append_ _ =
let call_site = CallSite.dummy in
let footprint_ap = AccessPath.Exact (AccessPath.of_id (Ident.create_none ()) Typ.Tvoid) in
let footprint_source = MockSource.make_footprint footprint_ap call_site in
let dummy_pdesc =
Cfg.create_proc_desc
(Cfg.create_cfg ())
(ProcAttributes.default Typ.Procname.empty_block !Config.curr_language) in
let footprint_source = MockSource.make_footprint footprint_ap dummy_pdesc in
let source_trace =
MockTrace.of_source source1 in
let footprint_trace =

Loading…
Cancel
Save