From 3cddd0489c0650b30033cf6ea20fa8d95a263e99 Mon Sep 17 00:00:00 2001 From: Dulma Rodriguez Date: Wed, 19 Aug 2015 17:22:48 -0100 Subject: [PATCH] [clang] Use the map of pointers to find method declarations and build method signatures Summary: Use the map of pointers to find method declarations and build method signatures. Remove the need for having an extra map for method signatures (and remove that map). --- infer/src/clang/cFrontend.ml | 3 +- infer/src/clang/cMethod_decl.ml | 25 ++++++----- infer/src/clang/cMethod_decl.mli | 6 +-- infer/src/clang/cMethod_signature.ml | 14 ------ infer/src/clang/cMethod_signature.mli | 6 --- infer/src/clang/cMethod_trans.ml | 36 ++++++++++------ infer/src/clang/cMethod_trans.mli | 7 +-- infer/src/clang/cModule_type.ml | 5 ++- infer/src/clang/cTrans.ml | 54 ++++++++++++------------ infer/src/clang/cTrans_utils.ml | 61 ++++++++++++++++++--------- infer/src/clang/cTrans_utils.mli | 4 +- 11 files changed, 115 insertions(+), 106 deletions(-) diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index 87ded84f0..3e0b475a3 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -29,7 +29,7 @@ let rec translate_one_declaration tenv cg cfg namespace parent_dec dec = let open Clang_ast_t in match dec with | FunctionDecl(di, name_info, qt, fdecl_info) -> - CMethod_declImpl.function_decl tenv cfg cg namespace dec None CContext.ContextNoCls + CMethod_declImpl.function_decl tenv cfg cg namespace dec None | TypedefDecl (decl_info, name_info, opt_type, _, typedef_decl_info) -> let name = name_info.Clang_ast_t.ni_name in CTypes_decl.do_typedef_declaration tenv namespace @@ -124,7 +124,6 @@ let init_global_state source_file = DB.current_source := source_file; DB.Results_dir.init (); Ident.reset_name_generator (); - CMethod_signature.reset_map (); CGlobal_vars.reset_map (); CFrontend_config.global_translation_unit_decls := []; ObjcProperty_decl.reset_property_table (); diff --git a/infer/src/clang/cMethod_decl.ml b/infer/src/clang/cMethod_decl.ml index d1c05635d..8fc8f33d4 100644 --- a/infer/src/clang/cMethod_decl.ml +++ b/infer/src/clang/cMethod_decl.ml @@ -19,8 +19,7 @@ module type CMethod_decl = sig Clang_ast_t.decl list -> unit val function_decl : Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.decl -> - (Clang_ast_t.qual_type * bool * Procname.t * (Mangled.t * Sil.typ * bool) list) option -> - CContext.curr_class -> unit + CModule_type.block_data option -> unit val process_getter_setter : CContext.t -> Procname.t -> bool end @@ -90,32 +89,32 @@ struct CMethod_trans.create_external_procdesc cfg procname is_objc_method None; () - let function_decl tenv cfg cg namespace func_decl block_data_opt curr_class = + let function_decl tenv cfg cg namespace func_decl block_data_opt = Printing.log_out "\nResetting the goto_labels hashmap...\n"; CTrans_utils.GotoLabel.reset_all_labels (); (* C Language Std 6.8.6.1-1 *) + let is_anonym_block, captured_vars, curr_class = + match block_data_opt with + | Some (_, _, _, captured_vars, curr_class) -> true, captured_vars, curr_class + | None -> false, [], CContext.ContextNoCls in + let class_name = + if curr_class = CContext.ContextNoCls then None else Some (CContext.get_curr_class_name curr_class) in let ms, body_opt, param_decls = - CMethod_trans.method_signature_of_decl curr_class func_decl block_data_opt in + CMethod_trans.method_signature_of_decl class_name func_decl block_data_opt in match method_body_to_translate ms body_opt with | Some body -> (* Only in the case the function declaration has a defined body we create a procdesc *) let procname = CMethod_signature.ms_get_name ms in - let is_anonym_block, captured_vars = - match block_data_opt with - | Some (_, _, _, captured_vars) -> true, captured_vars - | None -> false, [] in if CMethod_trans.create_local_procdesc cfg tenv ms [body] captured_vars false then let is_instance = CMethod_signature.ms_is_instance ms in let is_objc_method = is_anonym_block in - let curr_class = if is_anonym_block then curr_class else CContext.ContextNoCls in let attributes = CMethod_signature.ms_get_attributes ms in - CMethod_signature.add ms; add_method tenv cg cfg curr_class procname namespace [body] is_objc_method is_instance captured_vars is_anonym_block param_decls attributes - | None -> CMethod_signature.add ms + | None -> () let process_method_decl tenv cg cfg namespace curr_class meth_decl ~is_objc = + let class_name = Some (CContext.get_curr_class_name curr_class) in let ms, body_opt, param_decls = - CMethod_trans.method_signature_of_decl curr_class meth_decl None in - CMethod_signature.add ms; + CMethod_trans.method_signature_of_decl class_name meth_decl None in match method_body_to_translate ms body_opt with | Some body -> let is_instance = CMethod_signature.ms_is_instance ms in diff --git a/infer/src/clang/cMethod_decl.mli b/infer/src/clang/cMethod_decl.mli index 0c4a623a3..6f0686d4e 100644 --- a/infer/src/clang/cMethod_decl.mli +++ b/infer/src/clang/cMethod_decl.mli @@ -14,8 +14,7 @@ module CMethod_decl_funct(T: CModule_type.CTranslation) : sig Clang_ast_t.decl list -> unit val function_decl : Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.decl -> - (Clang_ast_t.qual_type * bool * Procname.t * (Mangled.t * Sil.typ * bool) list) option -> - CContext.curr_class -> unit + CModule_type.block_data option -> unit val process_getter_setter : CContext.t -> Procname.t -> bool @@ -26,8 +25,7 @@ module type CMethod_decl = sig Clang_ast_t.decl list -> unit val function_decl : Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.decl -> - (Clang_ast_t.qual_type * bool * Procname.t * (Mangled.t * Sil.typ * bool) list) option -> - CContext.curr_class -> unit + CModule_type.block_data option -> unit val process_getter_setter : CContext.t -> Procname.t -> bool end diff --git a/infer/src/clang/cMethod_signature.ml b/infer/src/clang/cMethod_signature.ml index 4cd7a0c58..d8770b5ad 100644 --- a/infer/src/clang/cMethod_signature.ml +++ b/infer/src/clang/cMethod_signature.ml @@ -41,10 +41,6 @@ let ms_is_instance ms = let ms_is_generated ms = ms._is_generated -type methodMap = method_signature Procname.Map.t - -let methodMap = ref Procname.Map.empty - let make_ms procname args ret_type attributes loc is_instance is_generated = let meth_signature = { _name = procname; @@ -64,13 +60,3 @@ let ms_to_string ms = "Method "^(Procname.to_string ms._name)^gen^" "^ (Utils.list_to_string (fun (s1, s2, _) -> s1^", "^s2) ms._args)^"->"^ms._ret_type^" "^ Clang_ast_j.string_of_source_range ms._loc - -let find ms = - Procname.Map.find ms !methodMap - -let add ms = - try ignore (find ms._name) - with Not_found -> methodMap := Procname.Map.add ms._name ms !methodMap - -let reset_map () = - methodMap := Procname.Map.empty diff --git a/infer/src/clang/cMethod_signature.mli b/infer/src/clang/cMethod_signature.mli index ffda15dbb..4c0c13666 100644 --- a/infer/src/clang/cMethod_signature.mli +++ b/infer/src/clang/cMethod_signature.mli @@ -12,12 +12,6 @@ type method_signature -val add : method_signature -> unit - -val find : Procname.t -> method_signature - -val reset_map : unit -> unit - val ms_get_name : method_signature -> Procname.t val ms_get_args : method_signature -> (string * string * Clang_ast_t.stmt option) list diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 35bd541ef..7bf9c3a03 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -15,6 +15,8 @@ open CFrontend_utils module L = Logging +exception Invalid_declaration + (** When the methoc call is MCStatic, means that it is a class method. *) (** When it is MCVirtual, it means that it is an instance method and that *) (** the method to be called will be determined at runtime. If it is MCNoVirtual *) @@ -84,25 +86,23 @@ let build_method_signature decl_info procname function_method_decl_info is_insta let attributes = decl_info.Clang_ast_t.di_attributes in CMethod_signature.make_ms procname parameters qt attributes source_range is_instance_method is_generated -let method_signature_of_decl curr_class meth_decl block_data_opt = +let method_signature_of_decl class_name_opt meth_decl block_data_opt = let open Clang_ast_t in - match meth_decl, block_data_opt with - | FunctionDecl (decl_info, name_info, qt, fdi), _ -> + match meth_decl, block_data_opt, class_name_opt with + | FunctionDecl (decl_info, name_info, qt, fdi), _, _ -> let name = name_info.ni_name in let func_decl = Func_decl_info (fdi, CTypes.get_type qt) in let procname = General_utils.mk_procname_from_function name (CTypes.get_type qt) in let ms = build_method_signature decl_info procname func_decl false false false in ms, fdi.Clang_ast_t.fdi_body, fdi.Clang_ast_t.fdi_parameters - | CXXMethodDecl (decl_info, name_info, qt, fdi), _ -> - let class_name = CContext.get_curr_class_name curr_class in + | CXXMethodDecl (decl_info, name_info, qt, fdi), _, Some class_name -> let method_name = name_info.Clang_ast_t.ni_name in let typ = CTypes.get_type qt in let procname = General_utils.mk_procname_from_cpp_method class_name method_name typ in let method_decl = Cpp_Meth_decl_info (fdi, class_name, typ) in let ms = build_method_signature decl_info procname method_decl false false false in ms, fdi.Clang_ast_t.fdi_body, fdi.Clang_ast_t.fdi_parameters - | ObjCMethodDecl (decl_info, name_info, mdi), _ -> - let class_name = CContext.get_curr_class_name curr_class in + | ObjCMethodDecl (decl_info, name_info, mdi), _, Some class_name -> let method_name = name_info.ni_name in let is_instance = mdi.omdi_is_instance_method in let method_kind = Procname.objc_method_kind_of_bool is_instance in @@ -112,11 +112,20 @@ let method_signature_of_decl curr_class meth_decl block_data_opt = let ms = build_method_signature decl_info procname method_decl false false is_generated in ms, mdi.omdi_body, mdi.omdi_parameters | BlockDecl (decl_info, decl_list, decl_context_info, bdi), - Some (qt, is_instance, procname, _) -> + Some (qt, is_instance, procname, _, _), _ -> let func_decl = Block_decl_info (bdi, CTypes.get_type qt) in let ms = build_method_signature decl_info procname func_decl is_instance true false in ms, bdi.bdi_body, bdi.bdi_parameters - |_ -> assert false + | _ -> raise Invalid_declaration + +let method_signature_of_pointer class_name_opt pointer = + try + match Ast_utils.get_decl pointer with + | Some meth_decl -> + let ms, _, _ = method_signature_of_decl class_name_opt meth_decl None in + Some ms + | None -> None + with Invalid_declaration -> None let get_superclass_curr_class context = let retrive_super cname super_opt = @@ -140,20 +149,21 @@ let get_superclass_curr_class context = let get_class_selector_instance context obj_c_message_expr_info act_params = let selector = obj_c_message_expr_info.Clang_ast_t.omei_selector in + let pointer = obj_c_message_expr_info.Clang_ast_t.omei_decl_pointer in match obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind with - | `Class qt -> (CTypes.get_type qt, selector, MCStatic) + | `Class qt -> (CTypes.get_type qt, selector, pointer, MCStatic) | `Instance -> (match act_params with | (instance_obj, Sil.Tptr(t, _)):: _ | (instance_obj, t):: _ -> - (CTypes.classname_of_type t, selector, MCVirtual) + (CTypes.classname_of_type t, selector, pointer, MCVirtual) | _ -> assert false) | `SuperInstance -> let superclass = get_superclass_curr_class context in - (superclass, selector, MCNoVirtual) + (superclass, selector, pointer, MCNoVirtual) | `SuperClass -> let superclass = get_superclass_curr_class context in - (superclass, selector, MCStatic) + (superclass, selector, pointer, MCStatic) let get_formal_parameters tenv ms = let rec defined_parameters pl = diff --git a/infer/src/clang/cMethod_trans.mli b/infer/src/clang/cMethod_trans.mli index b3c899a0d..44228b2e7 100644 --- a/infer/src/clang/cMethod_trans.mli +++ b/infer/src/clang/cMethod_trans.mli @@ -28,10 +28,11 @@ val create_external_procdesc : Cfg.cfg -> Procname.t -> bool -> (Sil.typ * Sil.t val captured_vars_from_block_info : CContext.t -> Clang_ast_t.block_captured_variable list -> (Mangled.t * Sil.typ * bool) list val get_class_selector_instance : CContext.t -> Clang_ast_t.obj_c_message_expr_info -> (Sil.exp * Sil.typ) list - -> (string * string * method_call_type) + -> (string * string * Clang_ast_t.pointer option * method_call_type) val should_create_procdesc : Cfg.cfg -> Procname.t -> bool -> bool -> bool -val method_signature_of_decl : CContext.curr_class -> Clang_ast_t.decl -> - (Clang_ast_t.qual_type * bool * Procname.t * 'a list) option -> +val method_signature_of_decl : string option -> Clang_ast_t.decl -> CModule_type.block_data option -> CMethod_signature.method_signature * Clang_ast_t.stmt option * Clang_ast_t.decl list + +val method_signature_of_pointer : string option -> Clang_ast_t.pointer -> CMethod_signature.method_signature option diff --git a/infer/src/clang/cModule_type.ml b/infer/src/clang/cModule_type.ml index f4839c680..c2176d56b 100644 --- a/infer/src/clang/cModule_type.ml +++ b/infer/src/clang/cModule_type.ml @@ -7,6 +7,8 @@ * of patent rights can be found in the PATENTS file in the same directory. *) +type block_data = Clang_ast_t.qual_type * bool * Procname.t * (Mangled.t * Sil.typ * bool) list * CContext.curr_class + module type CTranslation = sig val instructions_trans : CContext.t -> Clang_ast_t.stmt list -> Cfg.Node.t -> Cfg.Node.t list @@ -15,8 +17,7 @@ end module type CMethod_declaration = sig val function_decl : Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.decl -> - (Clang_ast_t.qual_type * bool * Procname.t * (Mangled.t * Sil.typ * bool) list) option -> - CContext.curr_class -> unit + block_data option -> unit val process_getter_setter : CContext.t -> Procname.t -> bool end diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 6bb2b2f56..91af7978a 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -35,10 +35,11 @@ struct (*Returns the procname and whether is instance, according to the selector *) (* information and according to the method signature *) let get_callee_objc_method context obj_c_message_expr_info act_params = - let (class_name, method_name, mc_type) = + let (class_name, method_name, method_pointer_opt, mc_type) = CMethod_trans.get_class_selector_instance context obj_c_message_expr_info act_params in let is_instance = mc_type != CMethod_trans.MCStatic in let method_kind = Procname.objc_method_kind_of_bool is_instance in + let callee_pn = General_utils.mk_procname_from_objc_method class_name method_name method_kind in let open CContext in match CTrans_models.get_predefined_model_method_signature class_name method_name General_utils.mk_procname_from_objc_method with @@ -46,16 +47,19 @@ struct ignore (CMethod_trans.create_local_procdesc context.cfg context.tenv ms [] [] is_instance); CMethod_signature.ms_get_name ms, CMethod_trans.MCNoVirtual | None -> - let procname = General_utils.mk_procname_from_objc_method class_name method_name method_kind in - try - let callee_ms = CMethod_signature.find procname in - if not (M.process_getter_setter context procname) then - (ignore (CMethod_trans.create_local_procdesc context.cfg context.tenv callee_ms [] [] is_instance)); - procname, mc_type - with Not_found -> - let callee_pn = General_utils.mk_procname_from_objc_method class_name method_name method_kind in + let found_method = + match method_pointer_opt with + | Some pointer -> + (match CMethod_trans.method_signature_of_pointer (Some class_name) pointer with + | Some callee_ms -> + if not (M.process_getter_setter context callee_pn) then + (ignore (CMethod_trans.create_local_procdesc context.cfg context.tenv callee_ms [] [] is_instance)); + true + | None -> false) + | None -> false in + if not found_method then CMethod_trans.create_external_procdesc context.cfg callee_pn is_instance None; - callee_pn, mc_type + callee_pn, mc_type let add_autorelease_call context exp typ sil_loc = let method_name = Procname.c_get_method (Cfg.Procdesc.get_proc_name context.CContext.procdesc) in @@ -295,6 +299,7 @@ struct let typ = CTypes_decl.qual_type_to_sil_type context.tenv expr_info.Clang_ast_t.ei_qual_type in let name = get_name_decl_ref_exp_info decl_ref_expr_info stmt_info in let procname = Cfg.Procdesc.get_proc_name context.procdesc in + let pointer = CTrans_utils.get_decl_pointer decl_ref_expr_info in let is_function = match get_decl_kind decl_ref_expr_info with | `Function -> true @@ -320,6 +325,11 @@ struct | Some v -> (General_utils.mk_procname_from_function name v, CTypes_decl.parse_func_type name v) | None -> (Procname.from_string_c_fun name, None) in + (match CMethod_trans.method_signature_of_pointer None pointer with + | Some callee_ms -> + ignore (CMethod_trans.create_local_procdesc context.cfg context.tenv callee_ms [] [] false) + | None -> + CMethod_trans.create_external_procdesc context.cfg pname false None); 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; *) @@ -557,7 +567,7 @@ struct (Procname.to_string pn) <> CFrontend_config.builtin_object_size | _ -> true in let params_stmt = if should_translate_args then - CTrans_utils.assign_default_params params_stmt callee_pname_opt ~is_cxx_method:false + CTrans_utils.assign_default_params params_stmt None fun_exp_stmt ~is_cxx_method:false else [] in let res_trans_par = let l = list_map (fun i -> exec_with_self_exception instruction trans_state_param i) params_stmt in @@ -602,11 +612,6 @@ struct if not (SymExec.function_is_builtin callee_pname) then begin Cg.add_edge context.cg procname callee_pname; - try - let callee_ms = CMethod_signature.find callee_pname in - ignore (CMethod_trans.create_local_procdesc context.cfg context.tenv callee_ms [] [] false) - with Not_found -> - CMethod_trans.create_external_procdesc context.cfg callee_pname false None end | None -> ()); (match ret_id with @@ -638,8 +643,8 @@ struct let callee_pname = match sil_method with | Sil.Const (Sil.Cfun pn) -> pn | _ -> assert false (* method pointer not implemented, this shouldn't happen *) in - - let params_stmt = CTrans_utils.assign_default_params params_stmt (Some callee_pname) ~is_cxx_method:true in + let class_name_opt = Some (Procname.c_get_class callee_pname) in + let params_stmt = CTrans_utils.assign_default_params params_stmt class_name_opt fun_exp_stmt ~is_cxx_method:true in (* As we may have nodes coming from different parameters we need to *) (* call instruction for each parameter and collect the results *) (* afterwards. The 'instructions' function does not do that *) @@ -668,12 +673,6 @@ struct let result_trans_to_parent = PriorityNode.compute_results_to_parent trans_state_pri sil_loc nname si res_trans_tmp in Cg.add_edge context.CContext.cg procname callee_pname; - let cfg = context.CContext.cfg in - (try - let callee_ms = CMethod_signature.find callee_pname in - ignore (CMethod_trans.create_local_procdesc cfg context.CContext.tenv callee_ms [] [] false) - with Not_found -> - CMethod_trans.create_external_procdesc cfg callee_pname false None); match ret_id with | [] -> { result_trans_to_parent with exps = [] } | [ret_id'] -> { result_trans_to_parent with exps = [(Sil.Var ret_id', function_type)] } @@ -709,7 +708,7 @@ struct let l = list_map (fun i -> exec_with_self_exception instruction trans_state_param i) rest in obj_c_message_expr_info, collect_res_trans (fst_res_trans :: l) | [] -> obj_c_message_expr_info, empty_res_trans) in - let (class_type, _, _) = CMethod_trans.get_class_selector_instance context obj_c_message_expr_info res_trans_par.exps in + let (class_type, _, _, _) = CMethod_trans.get_class_selector_instance context obj_c_message_expr_info res_trans_par.exps in if (selector = CFrontend_config.class_method && CTypes.is_class method_type) then raise (Self.SelfClassException class_type) else if is_alloc_or_new then @@ -1764,9 +1763,8 @@ struct let all_captured_vars = captured_vars @ static_vars in let ids_instrs = list_map assign_captured_var all_captured_vars in let ids, instrs = list_split ids_instrs in - let block_data = (qual_type, context.is_instance, block_pname, all_captured_vars) in - M.function_decl context.tenv context.cfg context.cg context.namespace decl - (Some block_data) context.curr_class; + let block_data = (qual_type, context.is_instance, block_pname, all_captured_vars, context.curr_class) in + M.function_decl context.tenv context.cfg context.cg context.namespace decl (Some block_data); Cfg.set_procname_priority context.cfg block_pname; let captured_exps = list_map (fun id -> Sil.Var id) ids in let tu = Sil.Ctuple ((Sil.Const (Sil.Cfun block_pname)) :: captured_exps) in diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 038cba728..35ef1953d 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -571,6 +571,11 @@ let get_decl_kind decl_ref_expr_info = | Some decl_ref -> decl_ref.Clang_ast_t.dr_kind | None -> assert false +let get_decl_pointer decl_ref_expr_info = + match decl_ref_expr_info.Clang_ast_t.drti_decl_ref with + | Some decl_ref -> decl_ref.Clang_ast_t.dr_decl_pointer + | None -> assert false + (* From the manual: A selector is in a certain selector family if, ignoring any leading underscores, *) (* the first component of the selector either consists entirely of the name of *) (* the method family or it begins with that followed by character other than lower case letter.*) @@ -678,27 +683,43 @@ let is_dispatch_function stmt_list = | _ -> None)) | _ -> None -let assign_default_params params_stmt callee_pname_opt ~is_cxx_method = - match callee_pname_opt with +let rec pointer_of_call_expr stmt = + let open Clang_ast_t in + match stmt with + | DeclRefExpr(_, _, _, decl_ref_expr_info) -> + Some (get_decl_pointer decl_ref_expr_info) + | MemberExpr(_, _, _, member_expr_info) -> + let decl_ref = member_expr_info.Clang_ast_t.mei_decl_ref in + Some decl_ref.Clang_ast_t.dr_decl_pointer + | _ -> + match snd (Clang_ast_proj.get_stmt_tuple stmt) with + | [stmt] -> pointer_of_call_expr stmt + | _ -> None + +let assign_default_params params_stmt class_name_opt stmt ~is_cxx_method = + match pointer_of_call_expr stmt with + | Some pointer -> + (match CMethod_trans.method_signature_of_pointer class_name_opt pointer with + | Some callee_ms -> + (let args = CMethod_signature.ms_get_args callee_ms in + let args = if is_cxx_method then match args with _::tl -> tl | _ -> assert false + else args in + let replace_default_arg param = + match param with + | Clang_ast_t.CXXDefaultArgExpr _, (_, _, Some default_instr) -> + default_instr + | instr, _ -> instr in + try + let params_args = list_combine params_stmt args in + list_map replace_default_arg params_args + with Invalid_argument _ -> + (* list_combine failed because of different list lengths *) + Printing.log_err "Param count doesn't match %s\n" + (Procname.to_string (CMethod_signature.ms_get_name callee_ms)); + params_stmt) + | None -> params_stmt) | None -> params_stmt - | Some callee_pname -> - try - let callee_ms = CMethod_signature.find callee_pname in - let args = CMethod_signature.ms_get_args callee_ms in - let args = if is_cxx_method then match args with _::tl -> tl | _ -> assert false - else args in - let params_args = list_combine params_stmt args in - let replace_default_arg param = - match param with - | Clang_ast_t.CXXDefaultArgExpr _, (_, _, Some default_instr) -> default_instr - | instr, _ -> instr in - list_map replace_default_arg params_args - with - | Invalid_argument _ -> - (* list_combine failed because of different list lengths *) - Printing.log_err "Param count doesn't match %s\n" (Procname.to_string callee_pname); - params_stmt - | Not_found -> params_stmt + let is_block_enumerate_function mei = mei.Clang_ast_t.omei_selector = CFrontend_config.enumerateObjectsUsingBlock diff --git a/infer/src/clang/cTrans_utils.mli b/infer/src/clang/cTrans_utils.mli index 2f78c4747..5a8b37651 100644 --- a/infer/src/clang/cTrans_utils.mli +++ b/infer/src/clang/cTrans_utils.mli @@ -70,6 +70,8 @@ val get_name_decl_ref_exp_info : Clang_ast_t.decl_ref_expr_info -> Clang_ast_t.s val get_decl_kind : Clang_ast_t.decl_ref_expr_info -> Clang_ast_t.decl_kind +val get_decl_pointer : Clang_ast_t.decl_ref_expr_info -> Clang_ast_t.pointer + val is_enumeration_constant : Clang_ast_t.stmt -> bool val is_member_exp : Clang_ast_t.stmt -> bool @@ -203,7 +205,7 @@ val is_logical_negation_of_int : Sil.tenv -> Clang_ast_t.expr_info -> Clang_ast_ val is_dispatch_function : Clang_ast_t.stmt list -> int option -val assign_default_params : Clang_ast_t.stmt list -> Procname.t option -> +val assign_default_params : Clang_ast_t.stmt list -> string option -> Clang_ast_t.stmt -> is_cxx_method:bool -> Clang_ast_t.stmt list val is_block_enumerate_function : Clang_ast_t.obj_c_message_expr_info -> bool