From 256b74b289f57c7e709d25302e3bf6d026ffc60e Mon Sep 17 00:00:00 2001 From: Mehdi Bouaziz Date: Wed, 30 May 2018 16:26:16 -0700 Subject: [PATCH] proc_inline_synthetic_methods: got rid of refs Reviewed By: jeremydubreil Differential Revision: D8150793 fbshipit-source-id: 2a63f95 --- infer/src/IR/Cfg.ml | 39 ++++++++++++--------------------------- infer/src/IR/Procdesc.ml | 19 +++++++++++++++++-- infer/src/IR/Procdesc.mli | 8 +++++--- 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/infer/src/IR/Cfg.ml b/infer/src/IR/Cfg.ml index 7e08d94de..6ecbd03e8 100644 --- a/infer/src/IR/Cfg.ml +++ b/infer/src/IR/Cfg.ml @@ -84,15 +84,14 @@ let save_attributes source_file cfg = (** Inline a synthetic (access or bridge) method. *) let inline_synthetic_method ((ret_id, _) as ret) etl pdesc loc_call : Sil.instr option = - let modified = ref None in let found instr instr' = - modified := Some instr' ; L.(debug Analysis Verbose) "XX inline_synthetic_method found instr: %a@." (Sil.pp_instr Pp.text) instr ; L.(debug Analysis Verbose) - "XX inline_synthetic_method instr': %a@." (Sil.pp_instr Pp.text) instr' + "XX inline_synthetic_method instr': %a@." (Sil.pp_instr Pp.text) instr' ; + Some instr' in - let do_instr _ instr = + let do_instr instr = match (instr, etl) with | Sil.Load (_, Exp.Lfield (Exp.Var _, fn, ft), bt, _), [(* getter for fields *) (e1, _)] -> let instr' = Sil.Load (ret_id, Exp.Lfield (e1, fn, ft), bt, loc_call) in @@ -125,15 +124,15 @@ let inline_synthetic_method ((ret_id, _) as ret) etl pdesc loc_call : Sil.instr let instr' = Sil.Call (ret, Exp.Const (Const.Cfun pn), etl1, loc_call, cf) in found instr instr' | _ -> - () + None in - Procdesc.iter_instrs do_instr pdesc ; - !modified + Procdesc.find_map_instrs ~f:do_instr pdesc (** Find synthetic (access or bridge) Java methods in the procedure and inline them in the cfg. *) let proc_inline_synthetic_methods cfg pdesc : unit = - let instr_inline_synthetic_method = function + let instr_inline_synthetic_method instr = + match instr with | Sil.Call (ret_id_typ, Exp.Const (Const.Cfun (Typ.Procname.Java java_pn as pn)), etl, loc, _) -> ( match Typ.Procname.Hash.find cfg pn with @@ -143,28 +142,14 @@ let proc_inline_synthetic_methods cfg pdesc : unit = let is_synthetic = attributes.is_synthetic_method in let is_bridge = attributes.is_bridge_method in if is_access || is_bridge || is_synthetic then - inline_synthetic_method ret_id_typ etl pd loc - else None + inline_synthetic_method ret_id_typ etl pd loc |> Option.value ~default:instr + else instr | exception Caml.Not_found -> - None ) + instr ) | _ -> - None - in - let node_inline_synthetic_methods node = - let modified = ref false in - let do_instr instr = - match instr_inline_synthetic_method instr with - | None -> - instr - | Some instr' -> - modified := true ; - instr' - in - let instrs = Procdesc.Node.get_instrs node in - let instrs' = List.map ~f:do_instr instrs in - if !modified then Procdesc.Node.replace_instrs node instrs' + instr in - Procdesc.iter_nodes node_inline_synthetic_methods pdesc + Procdesc.replace_instrs pdesc ~f:instr_inline_synthetic_method let inline_java_synthetic_methods cfg = diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index 1fe23ce89..322b2db91 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -126,8 +126,11 @@ module Node = struct (** Add the instructions at the beginning of the list of instructions to execute *) let prepend_instrs node instrs = node.instrs <- instrs @ node.instrs - (** Replace the instructions to be executed. *) - let replace_instrs node instrs = node.instrs <- instrs + (** Map and replace the instructions to be executed *) + let replace_instrs node ~f = + let instrs' = IList.map_changed node.instrs ~equal:phys_equal ~f in + if not (phys_equal instrs' node.instrs) then node.instrs <- instrs' + (** Add declarations for local variables and return variable to the node *) let add_locals_ret_declaration node (proc_attributes: ProcAttributes.t) locals = @@ -306,6 +309,18 @@ let fold_instrs pdesc ~init ~f = fold_nodes ~f:fold_node ~init pdesc +let find_map_nodes pdesc ~f = List.find_map ~f (get_nodes pdesc) + +let find_map_instrs pdesc ~f = + let find_map_node node = List.find_map ~f (Node.get_instrs node) in + find_map_nodes ~f:find_map_node pdesc + + +let replace_instrs pdesc ~f = + let do_node node = Node.replace_instrs ~f node in + iter_nodes do_node pdesc + + (** fold between two nodes or until we reach a branching structure *) let fold_slope_range = let rec aux node visited acc ~f = diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index c8def2eca..3c9c758e4 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -101,9 +101,6 @@ module Node : sig val pp_instrs : Pp.env -> sub_instrs:bool -> Sil.instr option -> Format.formatter -> t -> unit (** Print extended instructions for the node, highlighting the given subinstruction if present *) - - val replace_instrs : t -> Sil.instr list -> unit - (** Replace the instructions to be executed. *) end (** Map with node id keys. *) @@ -139,6 +136,8 @@ val did_preanalysis : t -> bool val fold_instrs : t -> init:'accum -> f:('accum -> Node.t -> Sil.instr -> 'accum) -> 'accum (** fold over all nodes and their instructions *) +val find_map_instrs : t -> f:(Sil.instr -> 'a option) -> 'a option + val from_proc_attributes : ProcAttributes.t -> t (** Use [Cfg.create_proc_desc] if you are adding a proc desc to a cfg *) @@ -184,6 +183,9 @@ val is_java_synchronized : t -> bool val iter_instrs : (Node.t -> Sil.instr -> unit) -> t -> unit (** iterate over all nodes and their instructions *) +val replace_instrs : t -> f:(Sil.instr -> Sil.instr) -> unit +(** Map and replace the instructions to be executed *) + val iter_nodes : (Node.t -> unit) -> t -> unit (** iterate over all the nodes of a procedure *)