From b3d0461317a47cc9f714d2311637a662c41c5697 Mon Sep 17 00:00:00 2001 From: Jules Villard Date: Thu, 21 Nov 2019 08:17:05 -0800 Subject: [PATCH] [IR] kill PredSymb.func_attribute by moving sentinel attrs to its own ProcAttribute field Summary: This is a better home for knowing whether a function has sentinel args according to its prototype declaration. Reviewed By: dulmarod, artempyanykh Differential Revision: D18573919 fbshipit-source-id: 13f58eaa2 --- infer/src/IR/PredSymb.ml | 14 -------------- infer/src/IR/PredSymb.mli | 8 -------- infer/src/IR/ProcAttributes.ml | 15 +++++++-------- infer/src/IR/ProcAttributes.mli | 2 +- infer/src/biabduction/SymExec.ml | 16 +++++++--------- infer/src/clang/cMethod_trans.ml | 25 +++++++++---------------- 6 files changed, 24 insertions(+), 56 deletions(-) diff --git a/infer/src/IR/PredSymb.ml b/infer/src/IR/PredSymb.ml index 3aed76701..ee9038cd4 100644 --- a/infer/src/IR/PredSymb.ml +++ b/infer/src/IR/PredSymb.ml @@ -12,11 +12,6 @@ open! IStd module L = Logging module F = Format -type func_attribute = FA_sentinel of int * int (** __attribute__((sentinel(int, int))) *) -[@@deriving compare] - -let pp_func_attribute fmt = function FA_sentinel (i, j) -> F.fprintf fmt "sentinel(%d,%d)" i j - (** Visibility modifiers. *) type access = Default | Public | Private | Protected [@@deriving compare] @@ -33,15 +28,6 @@ let string_of_access = function "Protected" -(** Return the value of the FA_sentinel attribute in [attr_list] if it is found *) -let get_sentinel_func_attribute_value attr_list = - match attr_list with - | FA_sentinel (sentinel, null_pos) :: _ -> - Some (sentinel, null_pos) - | [] -> - None - - type mem_kind = | Mmalloc (** memory allocated with malloc *) | Mnew (** memory allocated with new *) diff --git a/infer/src/IR/PredSymb.mli b/infer/src/IR/PredSymb.mli index d18067930..278b4a8d0 100644 --- a/infer/src/IR/PredSymb.mli +++ b/infer/src/IR/PredSymb.mli @@ -9,17 +9,9 @@ (** The Smallfoot Intermediate Language: Predicate Symbols *) open! IStd -module F = Format (** {2 Programs and Types} *) -type func_attribute = FA_sentinel of int * int [@@deriving compare] - -val pp_func_attribute : F.formatter -> func_attribute -> unit - -val get_sentinel_func_attribute_value : func_attribute list -> (int * int) option -(** Return the value of the FA_sentinel attribute in [attr_list] if it is found *) - (** Visibility modifiers. *) type access = Default | Public | Private | Protected [@@deriving compare] diff --git a/infer/src/IR/ProcAttributes.ml b/infer/src/IR/ProcAttributes.ml index a294d2377..99058a922 100644 --- a/infer/src/IR/ProcAttributes.ml +++ b/infer/src/IR/ProcAttributes.ml @@ -43,7 +43,6 @@ type t = ; exceptions: string list (** exceptions thrown by the procedure *) ; formals: (Mangled.t * Typ.t) list (** name and type of formal parameters *) ; const_formals: int list (** list of indices of formals that are const-qualified *) - ; func_attributes: PredSymb.func_attribute list ; is_abstract: bool (** the procedure is abstract *) ; is_biabduction_model: bool (** the procedure is a model for the biabduction analysis *) ; is_bridge_method: bool (** the procedure is a bridge method *) @@ -54,6 +53,7 @@ type t = ; is_specialized: bool (** the procedure is a clone specialized for dynamic dispatch handling *) ; is_synthetic_method: bool (** the procedure is a synthetic method *) ; is_variadic: bool (** the procedure is variadic, only supported for Clang procedures *) + ; sentinel_attr: (int * int) option (** __attribute__((sentinel(int, int))) *) ; clang_method_kind: ClangMethodKind.t (** the kind of method the procedure is *) ; loc: Location.t (** location of this procedure in the source code *) ; translation_unit: SourceFile.t (** translation unit to which the procedure belongs *) @@ -70,7 +70,6 @@ let default translation_unit proc_name = ; exceptions= [] ; formals= [] ; const_formals= [] - ; func_attributes= [] ; is_abstract= false ; is_biabduction_model= false ; is_bridge_method= false @@ -81,6 +80,7 @@ let default translation_unit proc_name = ; is_specialized= false ; is_synthetic_method= false ; is_variadic= false + ; sentinel_attr= None ; clang_method_kind= ClangMethodKind.C_FUNCTION ; loc= Location.dummy ; translation_unit @@ -102,7 +102,6 @@ let pp f ; exceptions ; formals ; const_formals - ; func_attributes ; is_abstract ; is_biabduction_model ; is_bridge_method @@ -113,6 +112,7 @@ let pp f ; is_specialized ; is_synthetic_method ; is_variadic + ; sentinel_attr ; clang_method_kind ; loc ; translation_unit @@ -142,11 +142,6 @@ let pp f F.fprintf f "; const_formals= [@[%a@]]@," (Pp.semicolon_seq ~print_env:Pp.text_break F.pp_print_int) const_formals ; - if not ([%compare.equal: PredSymb.func_attribute list] default.func_attributes func_attributes) - then - F.fprintf f "; func_attributes= [@[%a@]]@," - (Pp.semicolon_seq ~print_env:Pp.text_break PredSymb.pp_func_attribute) - func_attributes ; pp_bool_default ~default:default.is_abstract "is_abstract" is_abstract f () ; pp_bool_default ~default:default.is_biabduction_model "is_model" is_biabduction_model f () ; pp_bool_default ~default:default.is_bridge_method "is_bridge_method" is_bridge_method f () ; @@ -160,6 +155,10 @@ let pp f pp_bool_default ~default:default.is_synthetic_method "is_synthetic_method" is_synthetic_method f () ; pp_bool_default ~default:default.is_variadic "is_variadic" is_variadic f () ; + if not ([%compare.equal: (int * int) option] default.sentinel_attr sentinel_attr) then + F.fprintf f "; sentinel_attr= %a@," + (Pp.option (Pp.pair ~fst:F.pp_print_int ~snd:F.pp_print_int)) + sentinel_attr ; if not (ClangMethodKind.equal default.clang_method_kind clang_method_kind) then F.fprintf f "; clang_method_kind= %a@," (Pp.of_string ~f:ClangMethodKind.to_string) diff --git a/infer/src/IR/ProcAttributes.mli b/infer/src/IR/ProcAttributes.mli index df64623e7..cf3a93b00 100644 --- a/infer/src/IR/ProcAttributes.mli +++ b/infer/src/IR/ProcAttributes.mli @@ -26,7 +26,6 @@ type t = ; exceptions: string list (** exceptions thrown by the procedure *) ; formals: (Mangled.t * Typ.t) list (** name and type of formal parameters *) ; const_formals: int list (** list of indices of formals that are const-qualified *) - ; func_attributes: PredSymb.func_attribute list ; is_abstract: bool (** the procedure is abstract *) ; is_biabduction_model: bool (** the procedure is a model for the biabduction analysis *) ; is_bridge_method: bool (** the procedure is a bridge method *) @@ -37,6 +36,7 @@ type t = ; is_specialized: bool (** the procedure is a clone specialized for dynamic dispatch handling *) ; is_synthetic_method: bool (** the procedure is a synthetic method *) ; is_variadic: bool (** the procedure is variadic, only supported for Clang procedures *) + ; sentinel_attr: (int * int) option (** __attribute__((sentinel(int, int))) *) ; clang_method_kind: ClangMethodKind.t (** the kind of method the procedure is *) ; loc: Location.t (** location of this procedure in the source code *) ; translation_unit: SourceFile.t (** source file where the procedure was captured *) diff --git a/infer/src/biabduction/SymExec.ml b/infer/src/biabduction/SymExec.ml index a1163a6f3..fd49ff9bb 100644 --- a/infer/src/biabduction/SymExec.ml +++ b/infer/src/biabduction/SymExec.ml @@ -1766,17 +1766,15 @@ and check_variadic_sentinel ?(fails_on_nil = false) n_formals (sentinel, null_po and check_variadic_sentinel_if_present ({Builtin.prop_; path; proc_name} as builtin_args) = match Summary.OnDisk.proc_resolve_attributes proc_name with - | None -> - [(prop_, path)] | Some callee_attributes -> ( - match - PredSymb.get_sentinel_func_attribute_value callee_attributes.ProcAttributes.func_attributes - with - | None -> - [(prop_, path)] - | Some sentinel_arg -> + match callee_attributes.ProcAttributes.sentinel_attr with + | Some sentinel -> let formals = callee_attributes.ProcAttributes.formals in - check_variadic_sentinel (List.length formals) sentinel_arg builtin_args ) + check_variadic_sentinel (List.length formals) sentinel builtin_args + | None -> + [(prop_, path)] ) + | None -> + [(prop_, path)] and sym_exec_objc_getter field ret_typ tenv ret_id pdesc pname loc args prop = diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 0e57634d6..ecb3dc4f0 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -122,20 +122,6 @@ let get_objc_method_data obj_c_message_expr_info = (selector, pointer, MCStatic) -let sil_func_attributes_of_attributes attrs = - let rec do_translation acc al = - match al with - | [] -> - List.rev acc - | `SentinelAttr (_attr_info, {Clang_ast_t.sai_sentinel= sentinel; sai_null_pos= null_pos}) :: tl - -> - do_translation (PredSymb.FA_sentinel (sentinel, null_pos) :: acc) tl - | _ :: tl -> - do_translation acc tl - in - do_translation [] attrs - - let should_create_procdesc cfg procname defined set_objc_accessor_attr = match Typ.Procname.Hash.find cfg procname with | previous_procdesc -> @@ -195,12 +181,19 @@ let get_objc_property_accessor tenv ms = None +let find_sentinel_attribute attrs = + List.find_map attrs ~f:(function + | `SentinelAttr (_attr_info, {Clang_ast_t.sai_sentinel= sentinel; sai_null_pos= null_pos}) -> + Some (sentinel, null_pos) + | _ -> + None ) + + (** Creates a procedure description. *) let create_local_procdesc ?(set_objc_accessor_attr = false) trans_unit_ctx cfg tenv ms fbody captured = let defined = not (List.is_empty fbody) in let proc_name = ms.CMethodSignature.name in - let attributes = sil_func_attributes_of_attributes ms.CMethodSignature.attributes in let clang_method_kind = ms.CMethodSignature.method_kind in let is_cpp_nothrow = ms.CMethodSignature.is_cpp_nothrow in let access = @@ -253,12 +246,12 @@ let create_local_procdesc ?(set_objc_accessor_attr = false) trans_unit_ctx cfg t ; const_formals ; has_added_return_param ; access - ; func_attributes= attributes ; is_defined= defined ; is_cpp_noexcept_method= is_cpp_nothrow ; is_biabduction_model= Config.biabduction_models_mode ; is_no_return= ms.CMethodSignature.is_no_return ; is_variadic= ms.CMethodSignature.is_variadic + ; sentinel_attr= find_sentinel_attribute ms.CMethodSignature.attributes ; loc= loc_start ; clang_method_kind ; objc_accessor= objc_property_accessor