refactor objc dispatch models

Summary: Move Objective-C dispatch models to IR to be able to reuse the same approach in Pulse.

Reviewed By: skcho

Differential Revision: D28550389

fbshipit-source-id: 163826647
master
Daiva Naudziuniene 4 years ago committed by Facebook GitHub Bot
parent ab7d569e50
commit 85eb72f7cd

@ -0,0 +1,29 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
let dispatch_models =
[ "_dispatch_once"
; "dispatch_async"
; "dispatch_after"
; "dispatch_group_async"
; "dispatch_barrier_async"
; "dispatch_group_notify" ]
let is_model proc_name = List.mem dispatch_models ~equal:String.equal (Procname.to_string proc_name)
let get_dispatch_closure_opt actual_params =
List.find_map actual_params ~f:(fun (exp, _) ->
match exp with
| Exp.Closure c when Procname.is_objc_block c.name ->
(* We assume that for these modelled functions, the block passed as parameter doesn't
have arguments, so we only pass the captured variables. *)
let args = List.map ~f:(fun (id_exp, _, typ, _) -> (id_exp, typ)) c.captured_vars in
Some (c.name, args)
| _ ->
None )

@ -8,3 +8,5 @@
open! IStd open! IStd
val is_model : Procname.t -> bool val is_model : Procname.t -> bool
val get_dispatch_closure_opt : (Exp.t * Typ.t) list -> (Procname.t * (Exp.t * Typ.t) list) option

@ -1,18 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
let dispatch_models =
[ "_dispatch_once"
; "dispatch_async"
; "dispatch_after"
; "dispatch_group_async"
; "dispatch_barrier_async"
; "dispatch_group_notify" ]
let is_model proc_name = List.mem dispatch_models ~equal:String.equal (Procname.to_string proc_name)

@ -1077,11 +1077,6 @@ let declare_locals_and_ret tenv pdesc (prop_ : Prop.normal Prop.t) =
prop' prop'
let get_closure_opt actual_params =
List.find_map actual_params ~f:(fun (exp, _) ->
match exp with Exp.Closure c when Procname.is_objc_block c.name -> Some c | _ -> None )
(** Execute [instr] with a symbolic heap [prop].*) (** Execute [instr] with a symbolic heap [prop].*)
let rec sym_exec let rec sym_exec
( {InterproceduralAnalysis.proc_desc= current_pdesc; analyze_dependency; err_log; tenv} as ( {InterproceduralAnalysis.proc_desc= current_pdesc; analyze_dependency; err_log; tenv} as
@ -1109,12 +1104,9 @@ let rec sym_exec
let par' = List.map ~f:(fun (id_exp, _, typ, _) -> (id_exp, typ)) c.captured_vars in let par' = List.map ~f:(fun (id_exp, _, typ, _) -> (id_exp, typ)) c.captured_vars in
Sil.Call (ret, proc_exp', par' @ par, loc, call_flags) Sil.Call (ret, proc_exp', par' @ par, loc, call_flags)
| Exp.Const (Const.Cfun callee_pname) when ObjCDispatchModels.is_model callee_pname -> ( | Exp.Const (Const.Cfun callee_pname) when ObjCDispatchModels.is_model callee_pname -> (
match get_closure_opt par with match ObjCDispatchModels.get_dispatch_closure_opt par with
| Some c -> | Some (cname, args) ->
(* We assume that for these modelled functions, the block passed as parameter doesn't Sil.Call (ret, Exp.Const (Const.Cfun cname), args, loc, call_flags)
have arguments, so we only pass the captured variables. *)
let args = List.map ~f:(fun (id_exp, _, typ, _) -> (id_exp, typ)) c.captured_vars in
Sil.Call (ret, Exp.Const (Const.Cfun c.name), args, loc, call_flags)
| None -> | None ->
Sil.Call (ret, exp', par, loc, call_flags) ) Sil.Call (ret, exp', par, loc, call_flags) )
| _ -> | _ ->

Loading…
Cancel
Save