diff --git a/infer/src/IR/BuiltinDecl.ml b/infer/src/IR/BuiltinDecl.ml index 0f0c5097f..73cd1ae65 100644 --- a/infer/src/IR/BuiltinDecl.ml +++ b/infer/src/IR/BuiltinDecl.ml @@ -21,11 +21,12 @@ let create_procname name = let create_objc_class_method class_name method_name = - let method_kind = Typ.Procname.ObjCClassMethod in + let method_kind = Typ.Procname.ObjC_Cpp.ObjCClassMethod in let tname = Typ.Name.Objc.from_string class_name in let pname = Typ.Procname.ObjC_Cpp - (Typ.Procname.objc_cpp tname method_name method_kind Typ.NoTemplate ~is_generic_model:false) + (Typ.Procname.ObjC_Cpp.make tname method_name method_kind Typ.NoTemplate + ~is_generic_model:false) in register pname ; pname diff --git a/infer/src/IR/Procdesc.ml b/infer/src/IR/Procdesc.ml index 87a0740a4..647d1704f 100644 --- a/infer/src/IR/Procdesc.ml +++ b/infer/src/IR/Procdesc.ml @@ -459,7 +459,7 @@ let is_specialized pdesc = attributes.ProcAttributes.is_specialized -(* true if pvar is a captred variable of a cpp lambda or obcj block *) +(* true if pvar is a captured variable of a cpp lambda or objc block *) let is_captured_var procdesc pvar = let procname = get_proc_name procdesc in let pvar_name = Pvar.get_name pvar in @@ -468,11 +468,15 @@ let is_captured_var procdesc pvar = in let pvar_matches (name, _) = Mangled.equal name pvar_name in let is_captured_var_cpp_lambda = - (* var is captured if the procedure is a lambda and the var is not in the locals or formals *) - Typ.Procname.is_cpp_lambda procname - && not - ( List.exists ~f:pvar_local_matches (get_locals procdesc) - || List.exists ~f:pvar_matches (get_formals procdesc) ) + match procname with + | Typ.Procname.ObjC_Cpp cpp_pname -> + (* var is captured if the procedure is a lambda and the var is not in the locals or formals *) + Typ.Procname.ObjC_Cpp.is_cpp_lambda cpp_pname + && not + ( List.exists ~f:pvar_local_matches (get_locals procdesc) + || List.exists ~f:pvar_matches (get_formals procdesc) ) + | _ -> + false in let is_captured_var_objc_block = (* var is captured if the procedure is a objc block and the var is in the captured *) diff --git a/infer/src/IR/ProcnameDispatcher.ml b/infer/src/IR/ProcnameDispatcher.ml index 0422079e5..f6e8f3b8e 100644 --- a/infer/src/IR/ProcnameDispatcher.ml +++ b/infer/src/IR/ProcnameDispatcher.ml @@ -23,7 +23,7 @@ type typ = Typ.t type c = Typ.Procname.c -type objc_cpp = Typ.Procname.objc_cpp +type objc_cpp = Typ.Procname.ObjC_Cpp.t type qual_name = QualifiedCppName.t @@ -184,9 +184,9 @@ let name_cons | _ -> None in - let on_objc_cpp f objc_cpp = - if String.equal name objc_cpp.Typ.Procname.method_name then - on_templated_name f (templated_name_of_class_name objc_cpp.Typ.Procname.class_name) + let on_objc_cpp f (objc_cpp: Typ.Procname.ObjC_Cpp.t) = + if String.equal name objc_cpp.method_name then + on_templated_name f (templated_name_of_class_name objc_cpp.class_name) else None in {on_objc_cpp; on_qual_name; get_markers} @@ -210,12 +210,12 @@ let all_names_cons on_templated_name_rec f (rest, []) in let on_templated_name = on_templated_name_rec in - let on_objc_cpp f objc_cpp = + let on_objc_cpp f (objc_cpp: Typ.Procname.ObjC_Cpp.t) = match on_objc_cpp f objc_cpp with | Some _ as some -> some | None -> - on_templated_name f (templated_name_of_class_name objc_cpp.Typ.Procname.class_name) + on_templated_name f (templated_name_of_class_name objc_cpp.class_name) in {on_templated_name; get_markers; path_extra= PathNonEmpty {on_objc_cpp}} @@ -232,14 +232,12 @@ let templ_begin | Some (f, captured_types) -> Some (f, captured_types, template_args) in - let on_objc_cpp f objc_cpp = + let on_objc_cpp f (objc_cpp: Typ.Procname.ObjC_Cpp.t) = match on_objc_cpp f objc_cpp with | None -> None | Some (f, captured_types) -> - let template_args = - template_args_of_template_spec_info objc_cpp.Typ.Procname.template_args - in + let template_args = template_args_of_template_spec_info objc_cpp.template_args in Some (f, captured_types, template_args) in {on_objc_cpp; on_templated_name; get_markers} diff --git a/infer/src/IR/Sil.ml b/infer/src/IR/Sil.ml index 0aba3fb3a..26a0280c2 100644 --- a/infer/src/IR/Sil.ml +++ b/infer/src/IR/Sil.ml @@ -416,13 +416,13 @@ let pp_instr pe0 f instr = let add_with_block_parameters_flag instr = match instr with - | Call (ret_id, Exp.Const Const.Cfun name, arg_ts, loc, cf) -> + | Call (ret_id, Exp.Const Const.Cfun pname, arg_ts, loc, cf) -> if List.exists ~f:(fun (exp, _) -> Exp.is_objc_block_closure exp) arg_ts - && (Typ.Procname.is_objc_method name || Typ.Procname.is_c_function name) + && Typ.Procname.is_clang pname (* 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') + Call (ret_id, Exp.Const (Const.Cfun pname), arg_ts, loc, cf') else instr | _ -> instr diff --git a/infer/src/IR/Typ.ml b/infer/src/IR/Typ.ml index 22af97f49..889b9264e 100644 --- a/infer/src/IR/Typ.ml +++ b/infer/src/IR/Typ.ml @@ -694,6 +694,89 @@ module Procname = struct match List.last parameters with Some (_, "java.lang.Object[]") -> true | _ -> false end + module ObjC_Cpp = struct + type kind = + | CPPMethod of string option + | CPPConstructor of (string option * bool) + | CPPDestructor of string option + | ObjCClassMethod + | ObjCInstanceMethod + | ObjCInternalMethod + [@@deriving compare] + + type t = + { method_name: string + ; class_name: Name.t + ; kind: kind + ; template_args: template_spec_info + ; is_generic_model: bool } + [@@deriving compare] + + let make class_name method_name kind template_args ~is_generic_model = + {class_name; method_name; kind; template_args; is_generic_model} + + + let get_class_name objc_cpp = Name.name objc_cpp.class_name + + let get_class_type_name objc_cpp = objc_cpp.class_name + + let get_class_qualifiers objc_cpp = Name.qual_name objc_cpp.class_name + + let objc_method_kind_of_bool is_instance = + if is_instance then ObjCInstanceMethod else ObjCClassMethod + + + let is_objc_constructor method_name = + String.equal method_name "new" || String.is_prefix ~prefix:"init" method_name + + + let is_objc_kind = function + | ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod -> + true + | _ -> + false + + + let is_objc_method {kind} = is_objc_kind kind + + let is_objc_dealloc method_name = String.equal method_name "dealloc" + + let is_destructor = function + | {kind= CPPDestructor _} -> + true + | name -> + is_objc_dealloc name.method_name + + + let is_constexpr = function {kind= CPPConstructor (_, true)} -> true | _ -> false + + let is_cpp_lambda {method_name} = String.is_substring ~substring:"operator()" method_name + + let kind_to_verbose_string = function + | CPPMethod m | CPPDestructor m -> + "(" ^ (match m with None -> "" | Some s -> s) ^ ")" + | CPPConstructor (m, is_constexpr) -> + "{" ^ (match m with None -> "" | Some s -> s) + ^ (if is_constexpr then "|constexpr" else "") ^ "}" + | ObjCClassMethod -> + "class" + | ObjCInstanceMethod -> + "instance" + | ObjCInternalMethod -> + "internal" + + + let to_string osig detail_level = + match detail_level with + | Simple -> + osig.method_name + | Non_verbose -> + Name.name osig.class_name ^ "_" ^ osig.method_name + | Verbose -> + let m_str = kind_to_verbose_string osig.kind in + Name.name osig.class_name ^ "_" ^ osig.method_name ^ m_str + end + (** Type of c procedure names. *) type c = { name: QualifiedCppName.t @@ -702,24 +785,6 @@ module Procname = struct ; is_generic_model: bool } [@@deriving compare] - type objc_cpp_method_kind = - | CPPMethod of string option (** with mangling *) - | CPPConstructor of (string option * bool) (** with mangling + is it constexpr? *) - | CPPDestructor of string option (** with mangling *) - | ObjCClassMethod - | ObjCInstanceMethod - | ObjCInternalMethod - [@@deriving compare] - - (** Type of Objective C and C++ procedure names: method signatures. *) - type objc_cpp = - { method_name: string - ; class_name: Name.t - ; kind: objc_cpp_method_kind - ; template_args: template_spec_info - ; is_generic_model: bool } - [@@deriving compare] - (** Type of Objective C block names. *) type block_name = string [@@deriving compare] @@ -729,7 +794,7 @@ module Procname = struct | C of c | Linters_dummy_method | Block of block_name - | ObjC_Cpp of objc_cpp + | ObjC_Cpp of ObjC_Cpp.t | WithBlockParameters of t * block_name list [@@deriving compare] @@ -737,10 +802,6 @@ module Procname = struct let hash = Hashtbl.hash - let objc_method_kind_of_bool is_instance = - if is_instance then ObjCInstanceMethod else ObjCClassMethod - - let block_name_of_procname procname = match procname with | Block block_name -> @@ -763,11 +824,6 @@ module Procname = struct ; is_generic_model= false } - (** Create an objc procedure name from a class_name and method_name. *) - let objc_cpp class_name method_name kind template_args ~is_generic_model = - {class_name; method_name; kind; template_args; is_generic_model} - - let with_block_parameters base blocks = WithBlockParameters (base, blocks) (** Create an objc procedure name from a class_name and method_name. *) @@ -775,11 +831,17 @@ module Procname = struct let is_java = function Java _ -> true | _ -> false + (* TODO: deprecate this unfortunately named function and use is_clang instead *) let is_c_method = function ObjC_Cpp _ -> true | _ -> false let is_c_function = function C _ -> true | _ -> false - let is_constexpr = function ObjC_Cpp {kind= CPPConstructor (_, true)} -> true | _ -> false + let is_clang = function + | ObjC_Cpp name -> + ObjC_Cpp.is_objc_method name + | name -> + is_c_function name + (** Replace the class name component of a procedure name. In case of Java, replace package and class name. *) @@ -805,11 +867,6 @@ module Procname = struct t - (** Get the class name of a Objective-C/C++ procedure name. *) - let objc_cpp_get_class_name objc_cpp = Name.name objc_cpp.class_name - - let objc_cpp_get_class_type_name objc_cpp = objc_cpp.class_name - (** Return the method/function of a procname. *) let rec get_method = function | ObjC_Cpp name -> @@ -829,9 +886,6 @@ module Procname = struct (** Return whether the procname is a block procname. *) let is_objc_block = function Block _ -> true | _ -> false - (** Return whether the procname is a cpp lambda. *) - let is_cpp_lambda procname = String.is_substring ~substring:"operator()" (get_method procname) - (** Return the language of the procedure. *) let get_language = function | ObjC_Cpp _ -> @@ -848,39 +902,14 @@ module Procname = struct Language.Java - let is_objc_constructor method_name = - String.equal method_name "new" || String.is_prefix ~prefix:"init" method_name - - - let is_objc_kind = function - | ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod -> - true - | _ -> - 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 -> String.equal js.method_name "" | ObjC_Cpp {kind= CPPConstructor _} -> true - | ObjC_Cpp {kind; method_name} when is_objc_kind kind -> - is_objc_constructor method_name - | _ -> - false - - - let is_objc_dealloc method_name = String.equal method_name "dealloc" - - (** [is_dealloc pname] returns true if [pname] is the dealloc method in Objective-C *) - let is_destructor = function - | ObjC_Cpp {kind= CPPDestructor _} -> - true - | ObjC_Cpp name -> - is_objc_dealloc name.method_name + | ObjC_Cpp {kind; method_name} when ObjC_Cpp.is_objc_kind kind -> + ObjC_Cpp.is_objc_constructor method_name | _ -> false @@ -913,32 +942,6 @@ module Procname = struct if verbose then match c2 with None -> plain | Some s -> plain ^ "{" ^ s ^ "}" else plain - let c_method_kind_verbose_str kind = - match kind with - | CPPMethod m | CPPDestructor m -> - "(" ^ (match m with None -> "" | Some s -> s) ^ ")" - | CPPConstructor (m, is_constexpr) -> - "{" ^ (match m with None -> "" | Some s -> s) ^ (if is_constexpr then "|constexpr" else "") - ^ "}" - | ObjCClassMethod -> - "class" - | ObjCInstanceMethod -> - "instance" - | ObjCInternalMethod -> - "internal" - - - let c_method_to_string osig detail_level = - match detail_level with - | Simple -> - osig.method_name - | Non_verbose -> - Name.name osig.class_name ^ "_" ^ osig.method_name - | Verbose -> - let m_str = c_method_kind_verbose_str osig.kind in - Name.name osig.class_name ^ "_" ^ osig.method_name ^ m_str - - let with_blocks_parameters_to_string base blocks to_string_f = let base_id = to_string_f base in String.concat ~sep:"_" (base_id :: blocks) @@ -952,7 +955,7 @@ module Procname = struct | C {name; mangled} -> to_readable_string (name, mangled) true | ObjC_Cpp osig -> - c_method_to_string osig Verbose + ObjC_Cpp.to_string osig Verbose | Block name -> name | WithBlockParameters (base, blocks) -> @@ -969,7 +972,7 @@ module Procname = struct | C {name; mangled} -> to_readable_string (name, mangled) false | ObjC_Cpp osig -> - c_method_to_string osig Non_verbose + ObjC_Cpp.to_string osig Non_verbose | Block name -> name | WithBlockParameters (base, blocks) -> @@ -986,7 +989,7 @@ module Procname = struct | C {name; mangled} -> to_readable_string (name, mangled) false ^ "()" | ObjC_Cpp osig -> - c_method_to_string osig Simple + ObjC_Cpp.to_string osig Simple | Block _ -> "block" | WithBlockParameters (base, _) -> @@ -1002,7 +1005,7 @@ module Procname = struct invariant when introducing new annonynous classes *) Str.global_replace (Str.regexp "$[0-9]+") "$_" (Java.to_string ~withclass:true pname Simple) - | ObjC_Cpp _ when is_objc_method p -> + | ObjC_Cpp m when ObjC_Cpp.is_objc_method m -> (* In Objective C, the list of parameters is part of the method name. To prevent the bug hash to change when a parameter is introduced or removed, only the part of the name before the first colon is used for the bug hash *) @@ -1044,14 +1047,12 @@ module Procname = struct let pp = pp end) - let objc_cpp_get_class_qualifiers objc_cpp = Name.qual_name objc_cpp.class_name - let get_qualifiers pname = match pname with | C {name} -> name | ObjC_Cpp objc_cpp -> - objc_cpp_get_class_qualifiers objc_cpp + ObjC_Cpp.get_class_qualifiers objc_cpp |> QualifiedCppName.append_qualifier ~qual:objc_cpp.method_name | _ -> QualifiedCppName.empty @@ -1068,7 +1069,7 @@ module Procname = struct | C {mangled} -> get_qual_name_str pname :: Option.to_list mangled |> String.concat ~sep:"#" | ObjC_Cpp objc_cpp -> - get_qual_name_str pname ^ "#" ^ c_method_kind_verbose_str objc_cpp.kind + get_qual_name_str pname ^ "#" ^ ObjC_Cpp.kind_to_verbose_string objc_cpp.kind | _ -> to_unique_id pname in diff --git a/infer/src/IR/Typ.mli b/infer/src/IR/Typ.mli index 5131d7f95..1c4185bcf 100644 --- a/infer/src/IR/Typ.mli +++ b/infer/src/IR/Typ.mli @@ -334,6 +334,53 @@ module Procname : sig (** Check if this is a class initializer. *) end + module ObjC_Cpp : sig + type kind = + | CPPMethod of string option (** with mangling *) + | CPPConstructor of (string option * bool) (** with mangling + is it constexpr? *) + | CPPDestructor of string option (** with mangling *) + | ObjCClassMethod + | ObjCInstanceMethod + | ObjCInternalMethod + [@@deriving compare] + + (** Type of Objective C and C++ procedure names: method signatures. *) + type t = + { method_name: string + ; class_name: Name.t + ; kind: kind + ; template_args: template_spec_info + ; is_generic_model: bool } + [@@deriving compare] + + val make : Name.t -> string -> kind -> template_spec_info -> is_generic_model:bool -> t + (** Create an objc procedure name from a class_name and method_name. *) + + val get_class_name : t -> string + + val get_class_type_name : t -> Name.t + + val get_class_qualifiers : t -> QualifiedCppName.t + + val objc_method_kind_of_bool : bool -> kind + (** Create ObjC method type from a bool is_instance. *) + + val is_objc_constructor : string -> bool + (** Check if this is a constructor method in Objective-C. *) + + val is_objc_dealloc : string -> bool + (** Check if this is a dealloc method in Objective-C. *) + + val is_destructor : t -> bool + (** Check if this is a dealloc method. *) + + val is_constexpr : t -> bool + (** Check if this is a constexpr function. *) + + val is_cpp_lambda : t -> bool + (** Return whether the procname is a cpp lambda. *) + end + (** Type of c procedure names. *) type c = private { name: QualifiedCppName.t @@ -341,22 +388,6 @@ module Procname : sig ; template_args: template_spec_info ; is_generic_model: bool } - type objc_cpp_method_kind = - | CPPMethod of string option (** with mangling *) - | CPPConstructor of (string option * bool) (** with mangling + is it constexpr? *) - | CPPDestructor of string option (** with mangling *) - | ObjCClassMethod - | ObjCInstanceMethod - | ObjCInternalMethod - - (** Type of Objective C and C++ procedure names. *) - type objc_cpp = private - { method_name: string - ; class_name: Name.t - ; kind: objc_cpp_method_kind - ; template_args: template_spec_info - ; is_generic_model: bool } - (** Type of Objective C block names. *) type block_name @@ -371,7 +402,7 @@ module Procname : sig | C of c | Linters_dummy_method | Block of block_name - | ObjC_Cpp of objc_cpp + | ObjC_Cpp of ObjC_Cpp.t | WithBlockParameters of t * block_name list [@@deriving compare] @@ -416,61 +447,30 @@ module Procname : sig val is_objc_block : t -> bool (** Return whether the procname is a block procname. *) - val is_cpp_lambda : t -> bool - (** Return whether the procname is a cpp lambda. *) - val hash_pname : t -> int (** Hash function for procname. *) val is_c_method : t -> bool - (** Check if this is an Objective-C/C++ method name. *) + (** Return true this is an Objective-C/C++ method name. *) - val is_c_function : t -> bool - (** Check if this is a C function name. *) - - 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_clang : t -> bool + (** Return true if this is a C, C++, or Objective-C procedure name *) val is_constructor : t -> bool (** Check if this is a constructor. *) - val is_constexpr : t -> bool - (** Check if this is a constexpr function. *) - val is_java : t -> bool (** Check if this is a Java procedure name. *) - val is_objc_dealloc : string -> bool - (** Check if this is a dealloc method in Objective-C. *) - - val is_destructor : t -> bool - (** Check if this is a dealloc method. *) - val mangled_objc_block : string -> t (** Create an objc block name. *) - val objc_cpp : - Name.t -> string -> objc_cpp_method_kind -> template_spec_info -> is_generic_model:bool - -> objc_cpp - (** Create an objc procedure name from a class_name and method_name. *) - val with_block_parameters : t -> block_name list -> t (** Create a procedure name instantiated with block parameters from a base procedure name and a list of block procedure names (the arguments). *) - val objc_cpp_get_class_name : objc_cpp -> string - (** Get the class name of a Objective-C/C++ procedure name. *) - - val objc_cpp_get_class_type_name : objc_cpp -> Name.t - val objc_cpp_replace_method_name : t -> string -> t - val objc_method_kind_of_bool : bool -> objc_cpp_method_kind - (** Create ObjC method type from a bool is_instance. *) - val is_infer_undefined : t -> bool (** Check if this is a special Infer undefined procedure. *) @@ -502,9 +502,6 @@ module Procname : sig val get_qualifiers : t -> QualifiedCppName.t (** get qualifiers of C/objc/C++ method/function *) - - val objc_cpp_get_class_qualifiers : objc_cpp -> QualifiedCppName.t - (** get qualifiers of a class owning objc/C++ method *) end module Fieldname : sig diff --git a/infer/src/backend/errdesc.ml b/infer/src/backend/errdesc.ml index d7fda7cfb..0cf933e5c 100644 --- a/infer/src/backend/errdesc.ml +++ b/infer/src/backend/errdesc.ml @@ -28,7 +28,7 @@ let is_one_of_classes = QualifiedCppName.Match.match_qualifiers let is_method_of_objc_cpp_class pname matcher = match pname with | Typ.Procname.ObjC_Cpp objc_cpp -> - let class_qual_opt = Typ.Procname.objc_cpp_get_class_qualifiers objc_cpp in + let class_qual_opt = Typ.Procname.ObjC_Cpp.get_class_qualifiers objc_cpp in is_one_of_classes matcher class_qual_opt | _ -> false diff --git a/infer/src/checkers/BoundedCallTree.ml b/infer/src/checkers/BoundedCallTree.ml index 6b02fb998..7e3b93763 100644 --- a/infer/src/checkers/BoundedCallTree.ml +++ b/infer/src/checkers/BoundedCallTree.ml @@ -115,7 +115,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct (Typ.Procname.Java.get_class_name java_proc) | Typ.Procname.ObjC_Cpp objc_cpp_prod -> String.equal frame.Stacktrace.class_str - (Typ.Procname.objc_cpp_get_class_name objc_cpp_prod) + (Typ.Procname.ObjC_Cpp.get_class_name objc_cpp_prod) | Typ.Procname.C _ -> true (* Needed for test code. *) | Typ.Procname.Block _ diff --git a/infer/src/checkers/Siof.ml b/infer/src/checkers/Siof.ml index 133159a0d..8c52577bd 100644 --- a/infer/src/checkers/Siof.ml +++ b/infer/src/checkers/Siof.ml @@ -137,9 +137,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct else None ) in Domain.join astate (NonBottom SiofTrace.empty, Domain.VarNames.of_list init) - | Call (_, Const Cfun callee_pname, _ :: actuals_without_self, loc, _) - when Typ.Procname.is_c_method callee_pname && Typ.Procname.is_constructor callee_pname - && Typ.Procname.is_constexpr callee_pname -> + | Call (_, Const Cfun (ObjC_Cpp cpp_pname as callee_pname), _ :: actuals_without_self, loc, _) + when Typ.Procname.is_constructor callee_pname && Typ.Procname.ObjC_Cpp.is_constexpr cpp_pname -> add_actuals_globals astate pdesc loc actuals_without_self | Call (_, Const Cfun callee_pname, actuals, loc, _) -> let callee_astate = @@ -267,7 +266,12 @@ let checker {Callbacks.proc_desc; tenv; summary; get_procs_in_file} : Specs.summ to figure this out when analyzing the function, but we might as well use the user's specification if it's given to us. This also serves as an optimization as this skips the analysis of the function. *) - if Typ.Procname.is_constexpr pname then Summary.update_summary initial summary + if match pname with + | ObjC_Cpp cpp_pname -> + Typ.Procname.ObjC_Cpp.is_constexpr cpp_pname + | _ -> + false + then Summary.update_summary initial summary else match Analyzer.compute_post proc_data ~initial with | Some post -> diff --git a/infer/src/clang/CProcname.ml b/infer/src/clang/CProcname.ml index 521f6f0ae..b6e544e8d 100644 --- a/infer/src/clang/CProcname.ml +++ b/infer/src/clang/CProcname.ml @@ -58,7 +58,7 @@ let mk_c_function translation_unit_context ?tenv name function_decl_info_opt = | Some (decl_info, function_decl_info) -> ( match function_decl_info.Clang_ast_t.fdi_storage_class with | Some "static" - (* when we model static functions, we cannot take the file into account to + (* when we model static functions, we cannot take the file into account to create a mangled name because the file of the model is different to the real file, thus the model won't work *) when not (CTrans_models.is_modelled_static_function (QualifiedCppName.to_qual_string name)) -> @@ -105,11 +105,11 @@ let mk_cpp_method ?tenv class_name method_name ?meth_decl mangled = let method_kind = match meth_decl with | Some Clang_ast_t.CXXConstructorDecl (_, _, _, _, {xmdi_is_constexpr}) -> - Typ.Procname.CPPConstructor (mangled, xmdi_is_constexpr) + Typ.Procname.ObjC_Cpp.CPPConstructor (mangled, xmdi_is_constexpr) | Some Clang_ast_t.CXXDestructorDecl _ -> - Typ.Procname.CPPDestructor mangled + Typ.Procname.ObjC_Cpp.CPPDestructor mangled | _ -> - Typ.Procname.CPPMethod mangled + Typ.Procname.ObjC_Cpp.CPPMethod mangled in let template_info, is_generic_model = match meth_decl with @@ -132,12 +132,12 @@ let mk_cpp_method ?tenv class_name method_name ?meth_decl mangled = (Typ.NoTemplate, false) in Typ.Procname.ObjC_Cpp - (Typ.Procname.objc_cpp class_name method_name method_kind template_info ~is_generic_model) + (Typ.Procname.ObjC_Cpp.make class_name method_name method_kind template_info ~is_generic_model) let mk_objc_method class_typename method_name method_kind = Typ.Procname.ObjC_Cpp - (Typ.Procname.objc_cpp class_typename method_name method_kind Typ.NoTemplate + (Typ.Procname.ObjC_Cpp.make class_typename method_name method_kind Typ.NoTemplate ~is_generic_model:false) @@ -188,7 +188,7 @@ end let objc_method_procname ?tenv decl_info method_name mdi = let class_typename = get_class_typename ?tenv decl_info in let is_instance = mdi.Clang_ast_t.omdi_is_instance_method in - let method_kind = Typ.Procname.objc_method_kind_of_bool is_instance in + let method_kind = Typ.Procname.ObjC_Cpp.objc_method_kind_of_bool is_instance in mk_objc_method class_typename method_name method_kind diff --git a/infer/src/clang/CProcname.mli b/infer/src/clang/CProcname.mli index 9fd29efd4..7a18e0341 100644 --- a/infer/src/clang/CProcname.mli +++ b/infer/src/clang/CProcname.mli @@ -29,7 +29,7 @@ module NoAstDecl : sig val cpp_method_of_string : Tenv.t -> Typ.Name.t -> string -> Typ.Procname.t val objc_method_of_string_kind : - Typ.Name.t -> string -> Typ.Procname.objc_cpp_method_kind -> Typ.Procname.t + Typ.Name.t -> string -> Typ.Procname.ObjC_Cpp.kind -> Typ.Procname.t end val mk_fresh_block_procname : Typ.Procname.t -> Typ.Procname.t diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 768320062..77caf8fac 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -296,7 +296,7 @@ let get_class_name_method_call_from_clang trans_unit_ctx tenv obj_c_message_expr | Some ms -> ( match CMethod_signature.ms_get_name ms with | Typ.Procname.ObjC_Cpp objc_cpp -> - Some (Typ.Procname.objc_cpp_get_class_type_name objc_cpp) + Some (Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp) | _ -> None ) | None -> @@ -529,7 +529,7 @@ let get_objc_property_accessor tenv ms = let class_tname = match CMethod_signature.ms_get_name ms with | Typ.Procname.ObjC_Cpp objc_cpp -> - Typ.Procname.objc_cpp_get_class_type_name objc_cpp + Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp | _ -> assert false in diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index d80ad650d..f6bc175c1 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -403,10 +403,12 @@ let get_method_name_from_context context = let is_objc_constructor context = - Typ.Procname.is_objc_constructor (get_method_name_from_context context) + Typ.Procname.ObjC_Cpp.is_objc_constructor (get_method_name_from_context context) -let is_objc_dealloc context = Typ.Procname.is_objc_dealloc (get_method_name_from_context context) +let is_objc_dealloc context = + Typ.Procname.ObjC_Cpp.is_objc_dealloc (get_method_name_from_context context) + let is_in_method context name = let current_method_name = get_method_name_from_context context in diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 3110dd313..1032b4912 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -28,7 +28,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s CMethod_trans.get_objc_method_data obj_c_message_expr_info in let is_instance = mc_type <> CMethod_trans.MCStatic in - let objc_method_kind = Typ.Procname.objc_method_kind_of_bool is_instance in + let objc_method_kind = Typ.Procname.ObjC_Cpp.objc_method_kind_of_bool is_instance in let method_kind = if is_instance then ProcAttributes.OBJC_INSTANCE else ProcAttributes.OBJC_CLASS in @@ -55,7 +55,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s let predefined_ms_opt = match proc_name with | Typ.Procname.ObjC_Cpp objc_cpp -> - let class_name = Typ.Procname.objc_cpp_get_class_type_name objc_cpp in + let class_name = Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp in CTrans_models.get_predefined_model_method_signature class_name selector CProcname.NoAstDecl.objc_method_of_string_kind CFrontend_config.ObjC | _ -> @@ -2435,7 +2435,13 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s this is ensured by creating a fresh pointer in `inject_destructors` *) if destr_trans_result.root_nodes <> [] then assert false ; - let is_destructor = Typ.Procname.is_destructor procname in + let is_destructor = + match procname with + | Typ.Procname.ObjC_Cpp cpp_pname -> + Typ.Procname.ObjC_Cpp.is_destructor cpp_pname + | _ -> + false + in let destructor_res = if is_destructor then cxx_inject_field_destructors_in_destructor_body trans_state_pri stmt_info @@ -3484,7 +3490,13 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s ; opaque_exp= None } in let procname = Procdesc.get_proc_name context.CContext.procdesc in - let is_destructor = Typ.Procname.is_destructor procname in + let is_destructor = + match procname with + | Typ.Procname.ObjC_Cpp cpp_pname -> + Typ.Procname.ObjC_Cpp.is_destructor cpp_pname + | _ -> + false + in let stmt_info, _ = Clang_ast_proj.get_stmt_tuple body in let destructor_res, body = if is_destructor_wrapper then diff --git a/infer/src/clang/cTrans_models.ml b/infer/src/clang/cTrans_models.ml index 4a25b50ca..3dab4d496 100644 --- a/infer/src/clang/cTrans_models.ml +++ b/infer/src/clang/cTrans_models.ml @@ -93,7 +93,7 @@ let get_predefined_ms_stringWithUTF8String class_name method_name mk_procname la Ast_expressions.create_char_star_type ~quals:(Typ.mk_type_quals ~is_const:true ()) () in let args = [(Mangled.from_string "x", char_star_type)] in - get_predefined_ms_method condition class_name method_name Typ.Procname.ObjCClassMethod + get_predefined_ms_method condition class_name method_name Typ.Procname.ObjC_Cpp.ObjCClassMethod mk_procname lang args id_type [] None @@ -101,8 +101,9 @@ let get_predefined_ms_is_kind_of_class class_name method_name mk_procname lang = let condition = String.equal method_name CFrontend_config.is_kind_of_class in let class_type = Ast_expressions.create_class_qual_type class_name in let args = [(Mangled.from_string CFrontend_config.self, class_type)] in - get_predefined_ms_method condition class_name method_name Typ.Procname.ObjCInstanceMethod - mk_procname lang args Ast_expressions.create_BOOL_type [] (Some BuiltinDecl.__instanceof) + get_predefined_ms_method condition class_name method_name + Typ.Procname.ObjC_Cpp.ObjCInstanceMethod mk_procname lang args Ast_expressions.create_BOOL_type + [] (Some BuiltinDecl.__instanceof) let get_predefined_model_method_signature class_name method_name mk_procname lang = diff --git a/infer/src/clang/cTrans_models.mli b/infer/src/clang/cTrans_models.mli index 7a5e22272..e87e72d89 100644 --- a/infer/src/clang/cTrans_models.mli +++ b/infer/src/clang/cTrans_models.mli @@ -28,6 +28,5 @@ val is_modeled_builtin : string -> bool val is_modeled_attribute : string -> bool val get_predefined_model_method_signature : - Typ.Name.t -> string - -> (Typ.Name.t -> string -> Typ.Procname.objc_cpp_method_kind -> Typ.Procname.t) + Typ.Name.t -> string -> (Typ.Name.t -> string -> Typ.Procname.ObjC_Cpp.kind -> Typ.Procname.t) -> CFrontend_config.clang_lang -> CMethod_signature.method_signature option diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index 20380bdba..cd3172271 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -381,7 +381,7 @@ let objc_new_trans trans_state ~alloc_builtin loc stmt_info cls_name function_ty let method_kind = ProcAttributes.OBJC_INSTANCE in let pname = CProcname.NoAstDecl.objc_method_of_string_kind cls_name CFrontend_config.init - Typ.Procname.ObjCInstanceMethod + Typ.Procname.ObjC_Cpp.ObjCInstanceMethod in CMethod_trans.create_external_procdesc trans_state.context.CContext.cfg pname method_kind None ; let args = [(alloc_ret_exp, alloc_ret_type)] in diff --git a/infer/src/concurrency/RacerD.ml b/infer/src/concurrency/RacerD.ml index 1a6e97c69..7ce9ea50e 100644 --- a/infer/src/concurrency/RacerD.ml +++ b/infer/src/concurrency/RacerD.ml @@ -1493,7 +1493,7 @@ let report_unsafe_accesses (aggregated_access_map: reported_access list AccessLi reported_writes= Typ.Procname.Set.empty; reported_reads= Typ.Procname.Set.empty } in let class_has_mutex_member objc_cpp tenv = - let class_name = Typ.Procname.objc_cpp_get_class_type_name objc_cpp in + let class_name = Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp in let matcher = QualifiedCppName.Match.of_fuzzy_qual_names ["std::mutex"] in Option.exists (Tenv.lookup tenv class_name) ~f:(fun class_str -> (* check if the class contains a member of type std::mutex *) diff --git a/infer/src/concurrency/RacerDConfig.ml b/infer/src/concurrency/RacerDConfig.ml index 9a6e8c394..6f4296c1a 100644 --- a/infer/src/concurrency/RacerDConfig.ml +++ b/infer/src/concurrency/RacerDConfig.ml @@ -274,8 +274,8 @@ module Models = struct ; "std::vector" ]) in function - | (Typ.Procname.ObjC_Cpp _ | C _) as pname -> - Typ.Procname.is_destructor pname + | Typ.Procname.ObjC_Cpp cpp_pname as pname -> + Typ.Procname.ObjC_Cpp.is_destructor cpp_pname || QualifiedCppName.Match.match_qualifiers (Lazy.force matcher) (Typ.Procname.get_qualifiers pname) | _ -> diff --git a/infer/src/quandary/ClangTrace.ml b/infer/src/quandary/ClangTrace.ml index cd2ea37a1..dee57017b 100644 --- a/infer/src/quandary/ClangTrace.ml +++ b/infer/src/quandary/ClangTrace.ml @@ -68,7 +68,7 @@ module SourceKind = struct let qualified_pname = Typ.Procname.get_qualifiers pname in match ( QualifiedCppName.to_list - (Typ.Name.unqualified_name (Typ.Procname.objc_cpp_get_class_type_name cpp_name)) + (Typ.Name.unqualified_name (Typ.Procname.ObjC_Cpp.get_class_type_name cpp_name)) , Typ.Procname.get_method pname ) with | ( ["std"; ("basic_istream" | "basic_iostream")] @@ -128,7 +128,7 @@ module SourceKind = struct | _ -> false in - let typename = Typ.Procname.objc_cpp_get_class_type_name cpp_pname in + let typename = Typ.Procname.ObjC_Cpp.get_class_type_name cpp_pname in PatternMatch.supertype_exists tenv is_thrift_service_ typename in (* taint all formals except for [this] *) @@ -149,7 +149,7 @@ module SourceKind = struct | Typ.Procname.ObjC_Cpp cpp_pname as pname -> let qualified_pname = F.sprintf "%s::%s" - (Typ.Procname.objc_cpp_get_class_name cpp_pname) + (Typ.Procname.ObjC_Cpp.get_class_name cpp_pname) (Typ.Procname.get_method pname) in if String.Set.mem endpoints qualified_pname then @@ -272,7 +272,7 @@ module SinkKind = struct | Typ.Procname.ObjC_Cpp cpp_name -> ( match ( QualifiedCppName.to_list - (Typ.Name.unqualified_name (Typ.Procname.objc_cpp_get_class_type_name cpp_name)) + (Typ.Name.unqualified_name (Typ.Procname.ObjC_Cpp.get_class_type_name cpp_name)) , Typ.Procname.get_method pname ) with | ( ["std"; ("basic_fstream" | "basic_ifstream" | "basic_ofstream")]