[objc] Add a new call flag for calls with objc blocks as parameters

Reviewed By: mbouaziz

Differential Revision: D6233408

fbshipit-source-id: fa60a79
master
Dulma Churchill 7 years ago committed by Facebook Github Bot
parent c542b65a42
commit 5902f6363b

@ -20,12 +20,14 @@ type t =
; cf_interface: bool
; cf_noreturn: bool
; cf_is_objc_block: bool
; cf_targets: Typ.Procname.t list }
; cf_targets: Typ.Procname.t list
; cf_with_block_parameters: bool }
[@@deriving compare]
let pp f cf =
if cf.cf_virtual then F.fprintf f " virtual" ;
if cf.cf_noreturn then F.fprintf f " noreturn"
if cf.cf_noreturn then F.fprintf f " noreturn" ;
if cf.cf_with_block_parameters then F.fprintf f " block_params"
let default =
@ -33,5 +35,6 @@ let default =
; cf_interface= false
; cf_noreturn= false
; cf_is_objc_block= false
; cf_with_block_parameters= false
; cf_targets= [] }

@ -20,7 +20,8 @@ type t =
; cf_interface: bool
; cf_noreturn: bool
; cf_is_objc_block: bool
; cf_targets: Typ.Procname.t list }
; cf_targets: Typ.Procname.t list
; cf_with_block_parameters: bool }
[@@deriving compare]
val pp : F.formatter -> t -> unit

@ -271,3 +271,9 @@ let pp_printenv pe pp_typ f e = pp_ pe (pp_typ pe) f e
let pp f e = pp_printenv Pp.text Typ.pp f e
let to_string e = F.asprintf "%a" pp e
let is_objc_block_closure = function
| Closure {name} ->
Typ.Procname.is_objc_block name
| _ ->
false

@ -133,3 +133,5 @@ val pp_printenv : Pp.env -> (Pp.env -> F.formatter -> Typ.t -> unit) -> F.format
val pp : F.formatter -> t -> unit
val to_string : t -> string
val is_objc_block_closure : t -> bool

@ -437,6 +437,20 @@ let pp_instr pe0 f instr =
color_post_wrapper changed pe0 f
let add_with_block_parameters_flag instr =
match instr with
| Call (ret_id, Exp.Const Const.Cfun name, arg_ts, loc, cf) ->
if List.exists ~f:(fun (exp, _) -> Exp.is_objc_block_closure exp) arg_ts
&& Typ.Procname.is_objc_method name
(* to be extended to other methods *)
then
let cf' = {cf with cf_with_block_parameters= true} in
Call (ret_id, Exp.Const (Const.Cfun name), arg_ts, loc, cf')
else instr
| _ ->
instr
(** Check if a pvar is a local pointing to a block in objc *)
let is_block_pvar pvar = Typ.has_block_prefix (Mangled.to_string (Pvar.get_name pvar))

@ -276,6 +276,11 @@ val block_pvar : Pvar.t
val is_block_pvar : Pvar.t -> bool
(** Check if a pvar is a local pointing to a block in objc *)
val add_with_block_parameters_flag : instr -> instr
(** Adds a with_blocks_parameters flag to a method call, when the arguments
contain an Objective-C block, and the method is an Objective-C method
(to be extended to other methods) *)
val hpred_get_lhs : hpred -> Exp.t
(** Return the lhs expression of a hpred *)

@ -898,6 +898,8 @@ module Procname = struct
false
let is_objc_method = function ObjC_Cpp {kind} -> is_objc_kind kind | _ -> false
(** [is_constructor pname] returns true if [pname] is a constructor *)
let is_constructor = function
| Java js ->

@ -353,6 +353,9 @@ module Procname : sig
val is_objc_constructor : string -> bool
(** Check if this is a constructor method in Objective-C. *)
val is_objc_method : t -> bool
(** Check if this is an Objective-C method. *)
val is_constructor : t -> bool
(** Check if this is a constructor. *)

@ -256,7 +256,8 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
(ret_id, params_sil, [], match ret_id with Some (i, t) -> [(Exp.Var i, t)] | None -> [])
in
let call_instr = Sil.Call (ret_id', function_sil, params, sil_loc, call_flags) in
{empty_res_trans with instrs= [call_instr]; exps= ret_exps; initd_exps}
let call_instr' = Sil.add_with_block_parameters_flag call_instr in
{empty_res_trans with instrs= [call_instr']; exps= ret_exps; initd_exps}
let stringLiteral_trans trans_state expr_info str =

@ -41,7 +41,7 @@ digraph iCFG {
"capture#A#instance.d411336575e4bf632a1828f5f5979726_2" [label="2: Exit A_capture \n " color=yellow style=filled]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$0=*&self:A* [line 47, column 4]\n n$1=*n$0._b:B* [line 47, column 4]\n n$2=*&self:A* [line 47, column 16]\n _fun_B_sHandler:(n$1:B*,(_fun_objc_blockA_capture_1,n$2):_fn_(*)) virtual [line 47, column 3]\n " shape="box"]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" [label="3: Message Call: sHandler: \n n$0=*&self:A* [line 47, column 4]\n n$1=*n$0._b:B* [line 47, column 4]\n n$2=*&self:A* [line 47, column 16]\n _fun_B_sHandler:(n$1:B*,(_fun_objc_blockA_capture_1,n$2):_fn_(*)) virtual block_params [line 47, column 3]\n " shape="box"]
"capture#A#instance.d411336575e4bf632a1828f5f5979726_3" -> "capture#A#instance.d411336575e4bf632a1828f5f5979726_2" ;

@ -11,7 +11,7 @@ digraph iCFG {
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_2" ;
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$2=*&self:B* [line 25, column 10]\n n$3=*n$2.h:int [line 25, column 10]\n n$4=*&self:B* const [line 26, column 11]\n _fun_B_foo:and:(n$3:int,(_fun_objc_blockB_f_1,n$4):_fn_(*)) [line 25, column 3]\n " shape="box"]
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" [label="4: Message Call: foo:and: \n n$2=*&self:B* [line 25, column 10]\n n$3=*n$2.h:int [line 25, column 10]\n n$4=*&self:B* const [line 26, column 11]\n _fun_B_foo:and:(n$3:int,(_fun_objc_blockB_f_1,n$4):_fn_(*)) block_params [line 25, column 3]\n " shape="box"]
"f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_4" -> "f#B#instance.f1371ff5e7f410d3df6a2e71ff0a814e_3" ;

@ -63,7 +63,7 @@ digraph iCFG {
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_2" [label="2: Exit MyBlock_array \n " color=yellow style=filled]
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_3" [label="3: Message Call: enumerateObjectsUsingBlock: \n n$0=*&a:NSArray* [line 21, column 4]\n _fun_NSArray_enumerateObjectsUsingBlock:(n$0:NSArray*,(_fun_objc_blockMyBlock_array_1):_fn_(*)) virtual [line 21, column 3]\n " shape="box"]
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_3" [label="3: Message Call: enumerateObjectsUsingBlock: \n n$0=*&a:NSArray* [line 21, column 4]\n _fun_NSArray_enumerateObjectsUsingBlock:(n$0:NSArray*,(_fun_objc_blockMyBlock_array_1):_fn_(*)) virtual block_params [line 21, column 3]\n " shape="box"]
"array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_3" -> "array#MyBlock#instance.8be6e5b5e968d186440e1931c9eb40de_2" ;

Loading…
Cancel
Save