move retain/release special handling to function_deref_trans

Summary:
We already have logic that deals with adding custom procnames in `function_deref_trans`. This diff simplifies `callExpr_trans` and removes
complex logic responsible for finding type of function.
There is no functional change intended (it will come in future diffs)

Reviewed By: dulmarod

Differential Revision: D3797839

fbshipit-source-id: 21fc13f
master
Andrzej Kotulski 9 years ago committed by Facebook Github Bot 7
parent 7461d40024
commit 21ecba2d17

@ -441,7 +441,7 @@ struct
let root_node' = GotoLabel.find_goto_label trans_state.context label_name sil_loc in
{ empty_res_trans with root_nodes = [root_node']; leaf_nodes = trans_state.succ_nodes }
let get_builtin_pname_opt name decl_opt =
let get_builtin_pname_opt name decl_opt type_ptr =
let get_deprecated_attr_arg decl =
let open Clang_ast_t in
let decl_info = Clang_ast_proj.get_decl_tuple decl in
@ -461,6 +461,10 @@ struct
Some (Procname.from_string_c_fun attr)
| _ when CTrans_models.is_modeled_builtin name ->
Some (Procname.from_string_c_fun (CFrontend_config.infer ^ name))
| _ when CTrans_models.is_release_builtin name type_ptr ->
Some ModelBuiltins.__objc_release_cf
| _ when CTrans_models.is_retain_builtin name type_ptr ->
Some ModelBuiltins.__objc_retain_cf
| _ -> None
@ -472,13 +476,14 @@ struct
Option.may (call_translation context) decl_opt;
let name = Ast_utils.get_qualified_name name_info in
let typ = CTypes_decl.type_ptr_to_sil_type context.tenv type_ptr in
let pname = match get_builtin_pname_opt name decl_opt with
let pname = match get_builtin_pname_opt name decl_opt type_ptr with
| Some builtin_pname -> builtin_pname
| None -> CMethod_trans.create_procdesc_with_pointer context decl_ptr None name in
let address_of_function = not context.CContext.is_callee_expression in
(* If we are not translating a callee expression, *)
(* then the address of the function is being taken.*)
(* As e.g. in fun_ptr = foo; *)
let name = Procname.to_string pname in
let non_mangled_func_name =
if name = CFrontend_config.malloc &&
(Config.clang_lang = Config.OBJC ||
@ -576,7 +581,7 @@ struct
(* use qualified method name for builtin matching, but use unqualified name elsewhere *)
let qual_method_name = Ast_utils.get_qualified_name name_info in
let pname = match get_builtin_pname_opt qual_method_name decl_opt with
let pname = match get_builtin_pname_opt qual_method_name decl_opt type_ptr with
| Some builtin_pname -> builtin_pname
| None ->
let pname = CMethod_trans.create_procdesc_with_pointer context decl_ptr (Some class_name)
@ -890,8 +895,8 @@ struct
result_trans_subexprs) None callee_pname_opt with
| Some builtin -> builtin
| None ->
let callee_pname_opt', is_cf_retain_release =
CTrans_models.builtin_predefined_model fun_exp_stmt callee_pname_opt in
let is_cf_retain_release = Option.map_default
CTrans_models.is_cf_retain_release false callee_pname_opt in
let act_params =
let params = IList.tl (collect_exprs result_trans_subexprs) in
if IList.length params = IList.length params_stmt then
@ -903,12 +908,9 @@ struct
let act_params = if is_cf_retain_release then
(Exp.Const (Const.Cint IntLit.one), Typ.Tint Typ.IBool) :: act_params
else act_params in
let sil_fe' = match callee_pname_opt' with
| Some pn -> Exp.Const (Const.Cfun pn)
| _ -> sil_fe in
let res_trans_call =
let cast_trans_fun = cast_trans context act_params sil_loc function_type in
match Option.map_default cast_trans_fun None callee_pname_opt' with
match Option.map_default cast_trans_fun None callee_pname_opt with
| Some (instr, cast_exp) ->
{ empty_res_trans with
instrs = [instr];
@ -917,9 +919,9 @@ struct
let is_call_to_block = objc_exp_of_type_block fun_exp_stmt in
let call_flags =
{ CallFlags.default with CallFlags.cf_is_objc_block = is_call_to_block; } in
create_call_instr trans_state function_type sil_fe' act_params sil_loc
create_call_instr trans_state function_type sil_fe act_params sil_loc
call_flags ~is_objc_method:false in
let nname = "Call "^(Sil.exp_to_string sil_fe') in
let nname = "Call "^(Sil.exp_to_string sil_fe) in
let all_res_trans = result_trans_subexprs @ [res_trans_call] in
let res_trans_to_parent = PriorityNode.compute_results_to_parent trans_state_pri
sil_loc nname si all_res_trans in
@ -927,7 +929,7 @@ struct
if not (Builtin.is_registered callee_pname) then
Cg.add_edge context.CContext.cg procname callee_pname
in
Option.may add_cg_edge callee_pname_opt';
Option.may add_cg_edge callee_pname_opt;
{ res_trans_to_parent with exps = res_trans_call.exps }
and cxx_method_construct_call_trans trans_state_pri result_trans_callee params_stmt

@ -36,15 +36,6 @@ let is_builtin_object_size pname =
let is_replace_with_deref_first_arg pname =
(Procname.to_string pname) = CFrontend_config.replace_with_deref_first_arg_attr
let rec get_func_type_from_stmt stmt =
match stmt with
| Clang_ast_t.DeclRefExpr(_, _, expr_info, _) ->
Some expr_info.Clang_ast_t.ei_type_ptr
| _ ->
match CFrontend_utils.Ast_utils.get_stmts_from_stmt stmt with
| stmt:: _ -> get_func_type_from_stmt stmt
| [] -> None
let is_retain_predefined_model typ pname =
let funct = Procname.to_string pname in
Core_foundation_model.is_core_lib_retain typ funct
@ -78,6 +69,18 @@ let is_modeled_builtin funct =
let is_modeled_attribute attr_name =
IList.mem string_equal attr_name CFrontend_config.modeled_function_attributes
let is_release_builtin funct fun_type =
let pn = Procname.from_string_c_fun funct in
let typ = Ast_utils.string_of_type_ptr fun_type in
if Specs.summary_exists pn then false
else is_release_predefined_model typ pn
let is_retain_builtin funct fun_type =
let pn = Procname.from_string_c_fun funct in
let typ = Ast_utils.string_of_type_ptr fun_type in
if Specs.summary_exists pn then false
else is_retain_predefined_model typ pn
let is_assert_log_s funct =
funct = CFrontend_config.assert_rtn ||
funct = CFrontend_config.assert_fail ||
@ -103,19 +106,9 @@ let is_toll_free_bridging pn =
funct = CFrontend_config.cf_autorelease ||
funct = CFrontend_config.ns_make_collectable
(** If the function is a builtin model, return the model, otherwise return the function *)
let builtin_predefined_model fun_stmt pname_opt =
match get_func_type_from_stmt fun_stmt with
| Some typ ->
let typ = Ast_utils.string_of_type_ptr typ in
(match pname_opt with
| Some pn when Specs.summary_exists pn -> pname_opt, false
| Some pn when is_retain_predefined_model typ pn ->
Some ModelBuiltins.__objc_retain_cf, true
| Some pn when is_release_predefined_model typ pn ->
Some ModelBuiltins.__objc_release_cf, true
| _ -> pname_opt, false)
| _ -> pname_opt, false
let is_cf_retain_release pn =
Procname.equal pn ModelBuiltins.__objc_retain_cf
|| Procname.equal pn ModelBuiltins.__objc_release_cf
(** If the function is a builtin model, return the model, otherwise return the function *)
let is_assert_log pname =

@ -23,18 +23,22 @@ val is_replace_with_deref_first_arg : Procname.t -> bool
val is_objc_memory_model_controlled : string -> bool
val builtin_predefined_model : Clang_ast_t.stmt -> Procname.t option -> Procname.t option * bool
val is_assert_log : Procname.t -> bool
val is_handleFailureInMethod : string -> bool
val is_modeled_builtin : string -> bool
val is_release_builtin : string -> Clang_ast_t.type_ptr -> bool
val is_retain_builtin : string -> Clang_ast_t.type_ptr -> bool
val is_modeled_attribute : string -> bool
val is_toll_free_bridging : Procname.t -> bool
val is_cf_retain_release : Procname.t -> bool
val get_predefined_model_method_signature : string -> string ->
(string -> string -> Procname.objc_cpp_method_kind -> Procname.t) ->
Config.clang_lang -> CMethod_signature.method_signature option

Loading…
Cancel
Save