[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
master
Jules Villard 5 years ago committed by Facebook Github Bot
parent a9df6a917f
commit b3d0461317

@ -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 *)

@ -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]

@ -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)

@ -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 *)

@ -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 =

@ -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

Loading…
Cancel
Save