diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index d3d577116..2108ee0d1 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -306,19 +306,18 @@ let fold_instrs pdesc ~init ~f = fold_nodes ~f:fold_node ~init pdesc -(** iterate between two nodes or until we reach a branching structure *) -let iter_slope_range f src_node dst_node = - let visited = ref NodeSet.empty in - let rec do_node node = - visited := NodeSet.add node !visited ; - f node ; +(** fold between two nodes or until we reach a branching structure *) +let fold_slope_range = + let rec aux node visited acc ~f = + let visited = NodeSet.add node visited in + let acc = f acc node in match Node.get_succs node with - | [n] -> - if not (NodeSet.mem n !visited) && not (Node.equal node dst_node) then do_node n + | [n] when not (NodeSet.mem n visited) -> + aux n visited acc ~f | _ -> - () + acc in - do_node src_node + fun src_node dst_node ~init ~f -> aux src_node (NodeSet.singleton dst_node) init ~f (** Set the exit node of the proc desc *) diff --git a/infer/src/IR/Procdesc.mli b/infer/src/IR/Procdesc.mli index adefb9965..0af4e930c 100644 --- a/infer/src/IR/Procdesc.mli +++ b/infer/src/IR/Procdesc.mli @@ -187,8 +187,8 @@ val iter_instrs : (Node.t -> Sil.instr -> unit) -> t -> unit val iter_nodes : (Node.t -> unit) -> t -> unit (** iterate over all the nodes of a procedure *) -val iter_slope_range : (Node.t -> unit) -> Node.t -> Node.t -> unit -(** iterate between two nodes or until we reach a branching structure *) +val fold_slope_range : Node.t -> Node.t -> init:'accum -> f:('accum -> Node.t -> 'accum) -> 'accum +(** fold between two nodes or until we reach a branching structure *) val set_succs_exn_only : Node.t -> Node.t list -> unit diff --git a/infer/src/absint/PatternMatch.ml b/infer/src/absint/PatternMatch.ml index 20ec47ed3..60d59e142 100644 --- a/infer/src/absint/PatternMatch.ml +++ b/infer/src/absint/PatternMatch.ml @@ -236,24 +236,22 @@ let method_is_initializer (tenv: Tenv.t) (proc_attributes: ProcAttributes.t) : b (** Get the vararg values by looking for array assignments to the pvar. *) let java_get_vararg_values node pvar idenv = - let values = ref [] in - let do_instr = function + let values_of_instr acc = function | Sil.Store (Exp.Lindex (array_exp, _), _, content_exp, _) when Exp.equal (Exp.Lvar pvar) (Idenv.expand_expr idenv array_exp) -> (* Each vararg argument is an assignment to a pvar denoting an array of objects. *) - values := content_exp :: !values + content_exp :: acc | _ -> - () + acc in - let do_node n = List.iter ~f:do_instr (Procdesc.Node.get_instrs n) in - let () = - match Errdesc.find_program_variable_assignment node pvar with - | Some (node', _) -> - Procdesc.iter_slope_range do_node node' node - | None -> - () + let values_of_node acc n = + Procdesc.Node.get_instrs n |> List.fold ~f:values_of_instr ~init:acc in - !values + match Errdesc.find_program_variable_assignment node pvar with + | Some (node', _) -> + Procdesc.fold_slope_range node' node ~f:values_of_node ~init:[] + | None -> + [] let proc_calls resolve_attributes pdesc filter : (Typ.Procname.t * ProcAttributes.t) list =