[IR] Refactor annotation types into separate module

Reviewed By: sblackshear

Differential Revision: D3930166

fbshipit-source-id: 43465c8
master
Josh Berdine 9 years ago committed by Facebook Github Bot 7
parent 74c8198826
commit 44e2c32524

@ -0,0 +1,107 @@
/*
* vim: set ft=rust:
* vim: set ft=reason:
*
* Copyright (c) 2009 - 2013 Monoidics ltd.
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
open! Utils;
/** The Smallfoot Intermediate Language: Annotations */
let module L = Logging;
let module F = Format;
/** Type to represent one @Annotation. */
type t = {
class_name: string, /** name of the annotation */
parameters: list string /** currently only one string parameter */
};
/** Compare function for annotations. */
let compare a1 a2 => {
let n = string_compare a1.class_name a2.class_name;
if (n != 0) {
n
} else {
IList.compare string_compare a1.parameters a2.parameters
}
};
/** Pretty print an annotation. */
let pp fmt annotation => F.fprintf fmt "@@%s" annotation.class_name;
let module Map = PrettyPrintable.MakePPMap {
type nonrec t = t;
let compare = compare;
let pp_key = pp;
};
let module Item = {
/** Annotation for one item: a list of annotations with visibility. */
type nonrec t = list (t, bool);
/** Compare function for annotation items. */
let compare ia1 ia2 => {
let cmp (a1, b1) (a2, b2) => {
let n = compare a1 a2;
if (n != 0) {
n
} else {
bool_compare b1 b2
}
};
IList.compare cmp ia1 ia2
};
/** Pretty print an item annotation. */
let pp fmt ann => {
let pp fmt (a, _) => pp fmt a;
F.fprintf fmt "<%a>" (pp_seq pp) ann
};
let to_string ann => {
let pp fmt () => pp fmt ann;
pp_to_string pp ()
};
/** Empty item annotation. */
let empty = [];
/** Check if the item annodation is empty. */
let is_empty ia => ia == [];
};
let module Class = {
let objc_str = "ObjC-Class";
let cpp_str = "Cpp-Class";
let of_string class_string => [({class_name: class_string, parameters: []}, true)];
let objc = of_string objc_str;
let cpp = of_string cpp_str;
};
let module Method = {
/** Annotation for a method: return value and list of parameters. */
type t = (Item.t, list Item.t);
/** Compare function for Method annotations. */
let compare (ia1, ial1) (ia2, ial2) => IList.compare Item.compare [ia1, ...ial1] [ia2, ...ial2];
/** Pretty print a method annotation. */
let pp s fmt (ia, ial) => F.fprintf fmt "%a %s(%a)" Item.pp ia s (pp_seq Item.pp) ial;
/** Empty method annotation. */
let empty = ([], []);
/** Check if the method annodation is empty. */
let is_empty (ia, ial) => IList.for_all Item.is_empty [ia, ...ial];
};

@ -0,0 +1,72 @@
/*
* vim: set ft=rust:
* vim: set ft=reason:
*
* Copyright (c) 2009 - 2013 Monoidics ltd.
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
open! Utils;
/** The Smallfoot Intermediate Language: Annotations */
let module F = Format;
/** Type to represent one @Annotation. */
type t = {
class_name: string, /** name of the annotation */
parameters: list string /** currently only one string parameter */
};
/** Compare function for annotations. */
let compare: t => t => int;
/** Pretty print an annotation. */
let pp: F.formatter => t => unit;
let module Map: PrettyPrintable.PPMap with type key = t;
let module Item: {
/** Annotation for one item: a list of annotations with visibility. */
type nonrec t = list (t, bool);
/** Compare function for annotation items. */
let compare: t => t => int;
/** Pretty print an item annotation. */
let pp: F.formatter => t => unit;
let to_string: t => string;
/** Empty item annotation. */
let empty: t;
/** Check if the item annodation is empty. */
let is_empty: t => bool;
};
let module Class: {let objc: Item.t; let cpp: Item.t;};
let module Method: {
/** Annotation for a method: return value and list of parameters. */
type t = (Item.t, list Item.t);
/** Compare function for Method annotations. */
let compare: t => t => int;
/** Empty method annotation. */
let empty: t;
/** Check if the method annodation is empty. */
let is_empty: t => bool;
/** Pretty print a method annotation. */
let pp: string => F.formatter => t => unit;
};

@ -165,7 +165,7 @@ type t =
| Aautorelease | Aautorelease
| Adangling of dangling_kind /** dangling pointer */ | Adangling of dangling_kind /** dangling pointer */
/** undefined value obtained by calling the given procedure, plus its return value annots */ /** undefined value obtained by calling the given procedure, plus its return value annots */
| Aundef of Procname.t Typ.item_annotation Location.t path_pos | Aundef of Procname.t Annot.Item.t Location.t path_pos
| Ataint of taint_info | Ataint of taint_info
| Auntaint of taint_info | Auntaint of taint_info
| Alocked | Alocked
@ -175,7 +175,7 @@ type t =
/** attributed exp is null due to a call to a method with given path as null receiver */ /** attributed exp is null due to a call to a method with given path as null receiver */
| Aobjc_null | Aobjc_null
/** value was returned from a call to the given procedure, plus the annots of the return value */ /** value was returned from a call to the given procedure, plus the annots of the return value */
| Aretval of Procname.t Typ.item_annotation | Aretval of Procname.t Annot.Item.t
/** denotes an object registered as an observers to a notification center */ /** denotes an object registered as an observers to a notification center */
| Aobserver | Aobserver
/** denotes an object unsubscribed from observers of a notification center */ /** denotes an object unsubscribed from observers of a notification center */
@ -224,7 +224,7 @@ let compare (att1: t) (att2: t) :int =>
if (n != 0) { if (n != 0) {
n n
} else { } else {
Typ.item_annotation_compare annots1 annots2 Annot.Item.compare annots1 annots2
} }
| (Aretval _, _) => (-1) | (Aretval _, _) => (-1)
| (_, Aretval _) => 1 | (_, Aretval _) => 1

@ -100,7 +100,7 @@ type t =
| Aautorelease | Aautorelease
| Adangling of dangling_kind /** dangling pointer */ | Adangling of dangling_kind /** dangling pointer */
/** undefined value obtained by calling the given procedure, plus its return value annots */ /** undefined value obtained by calling the given procedure, plus its return value annots */
| Aundef of Procname.t Typ.item_annotation Location.t path_pos | Aundef of Procname.t Annot.Item.t Location.t path_pos
| Ataint of taint_info | Ataint of taint_info
| Auntaint of taint_info | Auntaint of taint_info
| Alocked | Alocked
@ -110,7 +110,7 @@ type t =
/** attributed exp is null due to a call to a method with given path as null receiver */ /** attributed exp is null due to a call to a method with given path as null receiver */
| Aobjc_null | Aobjc_null
/** value was returned from a call to the given procedure, plus the annots of the return value */ /** value was returned from a call to the given procedure, plus the annots of the return value */
| Aretval of Procname.t Typ.item_annotation | Aretval of Procname.t Annot.Item.t
/** denotes an object registered as an observers to a notification center */ /** denotes an object registered as an observers to a notification center */
| Aobserver | Aobserver
/** denotes an object unsubscribed from observers of a notification center */ /** denotes an object unsubscribed from observers of a notification center */

@ -41,7 +41,7 @@ type t = {
language: Config.language, /** language of the procedure */ language: Config.language, /** language of the procedure */
loc: Location.t, /** location of this procedure in the source code */ loc: Location.t, /** location of this procedure in the source code */
mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */
method_annotation: Typ.method_annotation, /** annotations for java methods */ method_annotation: Annot.Method.t, /** annotations for java methods */
objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */
proc_flags: proc_flags, /** flags of the procedure */ proc_flags: proc_flags, /** flags of the procedure */
proc_name: Procname.t, /** name of the procedure */ proc_name: Procname.t, /** name of the procedure */
@ -68,7 +68,7 @@ let default proc_name language => {
language, language,
loc: Location.dummy, loc: Location.dummy,
locals: [], locals: [],
method_annotation: Typ.method_annotation_empty, method_annotation: Annot.Method.empty,
objc_accessor: None, objc_accessor: None,
proc_flags: proc_flags_empty (), proc_flags: proc_flags_empty (),
proc_name, proc_name,

@ -35,7 +35,7 @@ type t = {
language: Config.language, /** language of the procedure */ language: Config.language, /** language of the procedure */
loc: Location.t, /** location of this procedure in the source code */ loc: Location.t, /** location of this procedure in the source code */
mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */
method_annotation: Typ.method_annotation, /** annotations for java methods */ method_annotation: Annot.Method.t, /** annotations for java methods */
objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */
proc_flags: proc_flags, /** flags of the procedure */ proc_flags: proc_flags, /** flags of the procedure */
proc_name: Procname.t, /** name of the procedure */ proc_name: Procname.t, /** name of the procedure */

@ -49,7 +49,7 @@ let mk_struct:
statics::Typ.struct_fields? => statics::Typ.struct_fields? =>
methods::list Procname.t? => methods::list Procname.t? =>
supers::list Typename.t? => supers::list Typename.t? =>
annots::Typ.item_annotation? => annots::Annot.Item.t? =>
Typename.t => Typename.t =>
Typ.struct_typ; Typ.struct_typ;

@ -20,104 +20,6 @@ let module L = Logging;
let module F = Format; let module F = Format;
/** Type to represent one @Annotation. */
type annotation = {
class_name: string, /** name of the annotation */
parameters: list string /** currently only one string parameter */
};
/** Compare function for annotations. */
let annotation_compare a1 a2 => {
let n = string_compare a1.class_name a2.class_name;
if (n != 0) {
n
} else {
IList.compare string_compare a1.parameters a2.parameters
}
};
/** Pretty print an annotation. */
let pp_annotation fmt annotation => F.fprintf fmt "@@%s" annotation.class_name;
let module AnnotMap = PrettyPrintable.MakePPMap {
type t = annotation;
let compare = annotation_compare;
let pp_key = pp_annotation;
};
/** Annotation for one item: a list of annotations with visibility. */
type item_annotation = list (annotation, bool);
/** Compare function for annotation items. */
let item_annotation_compare ia1 ia2 => {
let cmp (a1, b1) (a2, b2) => {
let n = annotation_compare a1 a2;
if (n != 0) {
n
} else {
bool_compare b1 b2
}
};
IList.compare cmp ia1 ia2
};
/** Pretty print an item annotation. */
let pp_item_annotation fmt item_annotation => {
let pp fmt (a, _) => pp_annotation fmt a;
F.fprintf fmt "<%a>" (pp_seq pp) item_annotation
};
let item_annotation_to_string ann => {
let pp fmt () => pp_item_annotation fmt ann;
pp_to_string pp ()
};
/** Empty item annotation. */
let item_annotation_empty = [];
/** Check if the item annodation is empty. */
let item_annotation_is_empty ia => ia == [];
let objc_class_str = "ObjC-Class";
let cpp_class_str = "Cpp-Class";
let class_annotation class_string => [({class_name: class_string, parameters: []}, true)];
let objc_class_annotation = class_annotation objc_class_str;
let cpp_class_annotation = class_annotation cpp_class_str;
/** Annotation for a method: return value and list of parameters. */
type method_annotation = (item_annotation, list item_annotation);
/** Compare function for Method annotations. */
let method_annotation_compare (ia1, ial1) (ia2, ial2) =>
IList.compare item_annotation_compare [ia1, ...ial1] [ia2, ...ial2];
/** Pretty print a method annotation. */
let pp_method_annotation s fmt (ia, ial) =>
F.fprintf fmt "%a %s(%a)" pp_item_annotation ia s (pp_seq pp_item_annotation) ial;
/** Empty method annotation. */
let method_annotation_empty = ([], []);
/** Check if the method annodation is empty. */
let method_annotation_is_empty (ia, ial) => IList.for_all item_annotation_is_empty [ia, ...ial];
/** Kinds of integers */ /** Kinds of integers */
type ikind = type ikind =
| IChar /** [char] */ | IChar /** [char] */
@ -291,7 +193,7 @@ type t =
| Tstruct of Typename.t /** structured value type name */ | Tstruct of Typename.t /** structured value type name */
| Tarray of t static_length /** array type with statically fixed length */; | Tarray of t static_length /** array type with statically fixed length */;
type struct_fields = list (Ident.fieldname, t, item_annotation); type struct_fields = list (Ident.fieldname, t, Annot.Item.t);
/** Type for a structured value. */ /** Type for a structured value. */
@ -300,7 +202,7 @@ type struct_typ = {
statics: struct_fields, /** static fields */ statics: struct_fields, /** static fields */
supers: list Typename.t, /** superclasses */ supers: list Typename.t, /** superclasses */
methods: list Procname.t, /** methods defined */ methods: list Procname.t, /** methods defined */
annots: item_annotation /** annotations */ annots: Annot.Item.t /** annotations */
}; };
type lookup = Typename.t => option struct_typ; type lookup = Typename.t => option struct_typ;
@ -343,7 +245,7 @@ let rec compare t1 t2 =>
let equal t1 t2 => compare t1 t2 == 0; let equal t1 t2 => compare t1 t2 == 0;
let fld_typ_ann_compare fta1 fta2 => let fld_typ_ann_compare fta1 fta2 =>
triple_compare Ident.fieldname_compare compare item_annotation_compare fta1 fta2; triple_compare Ident.fieldname_compare compare Annot.Item.compare fta1 fta2;
/** Pretty print a type declaration. /** Pretty print a type declaration.
@ -443,8 +345,7 @@ let internal_mk_struct
annots::annots=? annots::annots=?
() => { () => {
let mk_struct_ let mk_struct_
default:: default::default={fields: [], statics: [], methods: [], supers: [], annots: Annot.Item.empty}
default={fields: [], statics: [], methods: [], supers: [], annots: item_annotation_empty}
fields::fields=default.fields fields::fields=default.fields
statics::statics=default.statics statics::statics=default.statics
methods::methods=default.methods methods::methods=default.methods
@ -578,14 +479,14 @@ let has_block_prefix s =>
/** Check if type is a type for a block in objc */ /** Check if type is a type for a block in objc */
let is_block_type typ => has_block_prefix (to_string typ); let is_block_type typ => has_block_prefix (to_string typ);
let objc_ref_counter_annot = [({class_name: "ref_counter", parameters: []}, false)]; let objc_ref_counter_annot = [({Annot.class_name: "ref_counter", parameters: []}, false)];
/** Field used for objective-c reference counting */ /** Field used for objective-c reference counting */
let objc_ref_counter_field = (Ident.fieldname_hidden, Tint IInt, objc_ref_counter_annot); let objc_ref_counter_field = (Ident.fieldname_hidden, Tint IInt, objc_ref_counter_annot);
let is_objc_ref_counter_field (fld, _, a) => let is_objc_ref_counter_field (fld, _, a) =>
Ident.fieldname_is_hidden fld && item_annotation_compare a objc_ref_counter_annot == 0; Ident.fieldname_is_hidden fld && Annot.Item.compare a objc_ref_counter_annot == 0;
/** Java types by name */ /** Java types by name */

@ -18,69 +18,6 @@ open! Utils;
let module F = Format; let module F = Format;
/** Type to represent one @Annotation. */
type annotation = {
class_name: string, /** name of the annotation */
parameters: list string /** currently only one string parameter */
};
/** Compare function for annotations. */
let annotation_compare: annotation => annotation => int;
/** Pretty print an annotation. */
let pp_annotation: F.formatter => annotation => unit;
let module AnnotMap: PrettyPrintable.PPMap with type key = annotation;
/** Annotation for one item: a list of annotations with visibility. */
type item_annotation = list (annotation, bool);
/** Compare function for annotation items. */
let item_annotation_compare: item_annotation => item_annotation => int;
/** Pretty print an item annotation. */
let pp_item_annotation: F.formatter => item_annotation => unit;
let item_annotation_to_string: item_annotation => string;
/** Empty item annotation. */
let item_annotation_empty: item_annotation;
/** Check if the item annodation is empty. */
let item_annotation_is_empty: item_annotation => bool;
let objc_class_annotation: item_annotation;
let cpp_class_annotation: item_annotation;
/** Annotation for a method: return value and list of parameters. */
type method_annotation = (item_annotation, list item_annotation);
/** Compare function for Method annotations. */
let method_annotation_compare: method_annotation => method_annotation => int;
/** Empty method annotation. */
let method_annotation_empty: method_annotation;
/** Check if the method annodation is empty. */
let method_annotation_is_empty: method_annotation => bool;
/** Pretty print a method annotation. */
let pp_method_annotation: string => F.formatter => method_annotation => unit;
/** Kinds of integers */ /** Kinds of integers */
type ikind = type ikind =
| IChar /** [char] */ | IChar /** [char] */
@ -146,7 +83,7 @@ type t =
| Tstruct of Typename.t /** structured value type name */ | Tstruct of Typename.t /** structured value type name */
| Tarray of t static_length /** array type with statically fixed length */; | Tarray of t static_length /** array type with statically fixed length */;
type struct_fields = list (Ident.fieldname, t, item_annotation); type struct_fields = list (Ident.fieldname, t, Annot.Item.t);
/** Type for a structured value. */ /** Type for a structured value. */
@ -155,7 +92,7 @@ type struct_typ = private {
statics: struct_fields, /** static fields */ statics: struct_fields, /** static fields */
supers: list Typename.t, /** supers */ supers: list Typename.t, /** supers */
methods: list Procname.t, /** methods defined */ methods: list Procname.t, /** methods defined */
annots: item_annotation /** annotations */ annots: Annot.Item.t /** annotations */
}; };
type lookup = Typename.t => option struct_typ; type lookup = Typename.t => option struct_typ;
@ -163,7 +100,7 @@ type lookup = Typename.t => option struct_typ;
/** Comparision for fieldnames * types * item annotations. */ /** Comparision for fieldnames * types * item annotations. */
let fld_typ_ann_compare: let fld_typ_ann_compare:
(Ident.fieldname, t, item_annotation) => (Ident.fieldname, t, item_annotation) => int; (Ident.fieldname, t, Annot.Item.t) => (Ident.fieldname, t, Annot.Item.t) => int;
/** Comparision for types. */ /** Comparision for types. */
@ -217,7 +154,7 @@ let internal_mk_struct:
statics::struct_fields? => statics::struct_fields? =>
methods::list Procname.t? => methods::list Procname.t? =>
supers::list Typename.t? => supers::list Typename.t? =>
annots::item_annotation? => annots::Annot.Item.t? =>
unit => unit =>
struct_typ; struct_typ;
@ -246,7 +183,7 @@ let struct_typ_fld: lookup::lookup => default::t => Ident.fieldname => t => t;
/** Return the type of the field [fn] and its annotation, None if [typ] has no field named [fn] */ /** Return the type of the field [fn] and its annotation, None if [typ] has no field named [fn] */
let get_field_type_and_annotation: let get_field_type_and_annotation:
lookup::lookup => Ident.fieldname => t => option (t, item_annotation); lookup::lookup => Ident.fieldname => t => option (t, Annot.Item.t);
let is_objc_class: t => bool; let is_objc_class: t => bool;
@ -266,9 +203,9 @@ let is_block_type: t => bool;
/** Field used for objective-c reference counting */ /** Field used for objective-c reference counting */
let objc_ref_counter_field: (Ident.fieldname, t, item_annotation); let objc_ref_counter_field: (Ident.fieldname, t, Annot.Item.t);
let is_objc_ref_counter_field: (Ident.fieldname, t, item_annotation) => bool; let is_objc_ref_counter_field: (Ident.fieldname, t, Annot.Item.t) => bool;
let unsome: string => option t => t; let unsome: string => option t => t;

@ -91,8 +91,8 @@ val nullify_exp_with_objc_null : Tenv.t -> Prop.normal Prop.t -> Exp.t -> Prop.n
(** mark Exp.Var's or Exp.Lvar's as undefined *) (** mark Exp.Var's or Exp.Lvar's as undefined *)
val mark_vars_as_undefined : val mark_vars_as_undefined :
Tenv.t -> Prop.normal Prop.t -> Exp.t list -> Procname.t -> Typ.item_annotation -> Location.t -> Tenv.t -> Prop.normal Prop.t -> Exp.t list -> Procname.t -> Annot.Item.t ->
PredSymb.path_pos -> Prop.normal Prop.t Location.t -> PredSymb.path_pos -> Prop.normal Prop.t
(** type for arithmetic problems *) (** type for arithmetic problems *)
type arith_problem = type arith_problem =

@ -1018,10 +1018,10 @@ let cycle_has_weak_or_unretained_or_assign_field tenv cycle =
| [] -> false | [] -> false
| att:: _ when Config.unsafe_unret = att || Config.weak = att || Config.assign = att -> true | att:: _ when Config.unsafe_unret = att || Config.weak = att || Config.assign = att -> true
| _:: params' -> has_weak_or_unretained_or_assign params' in | _:: params' -> has_weak_or_unretained_or_assign params' in
let do_annotation (a, _) = let do_annotation ((a: Annot.t), _) =
((a.Typ.class_name = Config.property_attributes) || ((a.class_name = Config.property_attributes) ||
(a.Typ.class_name = Config.ivar_attributes)) (a.class_name = Config.ivar_attributes))
&& has_weak_or_unretained_or_assign a.Typ.parameters in && has_weak_or_unretained_or_assign a.parameters in
let rec do_cycle c = let rec do_cycle c =
match c with match c with
| [] -> false | [] -> false

@ -850,7 +850,7 @@ let execute_scan_function skip_n_arguments ({ Builtin.args } as call_args)
SymExec.unknown_or_scan_call SymExec.unknown_or_scan_call
~is_scan:true ~is_scan:true
None None
Typ.item_annotation_empty Annot.Item.empty
{ call_args with args = !varargs } { call_args with args = !varargs }
| _ -> raise (Exceptions.Wrong_argument_number __POS__) | _ -> raise (Exceptions.Wrong_argument_number __POS__)

@ -1495,7 +1495,7 @@ let expand_hpred_pointer =
let mangled = Mangled.from_string ("counterfeit" ^ string_of_int !count) in let mangled = Mangled.from_string ("counterfeit" ^ string_of_int !count) in
let name = Typename.TN_csu (Struct, mangled) in let name = Typename.TN_csu (Struct, mangled) in
incr count ; incr count ;
let fields = [(fld, cnt_typ, Typ.item_annotation_empty)] in let fields = [(fld, cnt_typ, Annot.Item.empty)] in
ignore (Tenv.mk_struct tenv ~fields name) ; ignore (Tenv.mk_struct tenv ~fields name) ;
Exp.Sizeof (Tstruct name, len, st) Exp.Sizeof (Tstruct name, len, st)
| _ -> | _ ->

@ -642,10 +642,10 @@ let add_guarded_by_constraints tenv prop lexp pdesc =
string_is_suffix guarded_by_str fully_qualified_this string_is_suffix guarded_by_str fully_qualified_this
| _ -> false in | _ -> false in
let extract_guarded_by_str item_annot = let extract_guarded_by_str item_annot =
let annot_extract_guarded_by_str (annot, _) = let annot_extract_guarded_by_str ((annot: Annot.t), _) =
if Annotations.annot_ends_with annot Annotations.guarded_by if Annotations.annot_ends_with annot Annotations.guarded_by
then then
match annot.Typ.parameters with match annot.parameters with
| [guarded_by_str] when not (excluded_guardedby_string guarded_by_str) -> | [guarded_by_str] when not (excluded_guardedby_string guarded_by_str) ->
Some guarded_by_str Some guarded_by_str
| _ -> | _ ->

@ -315,7 +315,7 @@ type phase = FOOTPRINT | RE_EXECUTION
type dependency_map_t = int Procname.Map.t type dependency_map_t = int Procname.Map.t
type call_summary = CallSite.Set.t Typ.AnnotMap.t type call_summary = CallSite.Set.t Annot.Map.t
(** Payload: results of some analysis *) (** Payload: results of some analysis *)
type payload = type payload =

@ -119,7 +119,7 @@ type phase = FOOTPRINT | RE_EXECUTION
type dependency_map_t = int Procname.Map.t type dependency_map_t = int Procname.Map.t
type call_summary = CallSite.Set.t Typ.AnnotMap.t type call_summary = CallSite.Set.t Annot.Map.t
(** Payload: results of some analysis *) (** Payload: results of some analysis *)
type payload = type payload =

@ -953,7 +953,7 @@ let load_ret_annots pname =
let ret_annots, _ = attrs.ProcAttributes.method_annotation in let ret_annots, _ = attrs.ProcAttributes.method_annotation in
ret_annots ret_annots
| None -> | None ->
Typ.item_annotation_empty Annot.Item.empty
let execute_store ?(report_deref_errors=true) pname pdesc tenv lhs_exp typ rhs_exp loc prop_ = let execute_store ?(report_deref_errors=true) pname pdesc tenv lhs_exp typ rhs_exp loc prop_ =
let execute_store_ pdesc tenv rhs_exp acc_in iter = let execute_store_ pdesc tenv rhs_exp acc_in iter =
@ -1190,7 +1190,7 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
L.d_str "Unknown function pointer "; Sil.d_exp fun_exp; L.d_str "Unknown function pointer "; Sil.d_exp fun_exp;
L.d_strln ", returning undefined value."; L.d_strln ", returning undefined value.";
let callee_pname = Procname.from_string_c_fun "__function_pointer__" in let callee_pname = Procname.from_string_c_fun "__function_pointer__" in
unknown_or_scan_call ~is_scan:false None Typ.item_annotation_empty Builtin.{ unknown_or_scan_call ~is_scan:false None Annot.Item.empty Builtin.{
pdesc= current_pdesc; instr; tenv; prop_= prop_r; path; ret_ids; args= n_actual_params; pdesc= current_pdesc; instr; tenv; prop_= prop_r; path; ret_ids; args= n_actual_params;
proc_name= callee_pname; loc; } proc_name= callee_pname; loc; }
end end

@ -26,7 +26,7 @@ val diverge : Prop.normal Prop.t -> Paths.Path.t -> (Prop.normal Prop.t * Paths.
val proc_call : Specs.summary -> Builtin.t val proc_call : Specs.summary -> Builtin.t
val unknown_or_scan_call : is_scan:bool -> Typ.t option -> Typ.item_annotation -> Builtin.t val unknown_or_scan_call : is_scan:bool -> Typ.t option -> Annot.Item.t -> Builtin.t
val check_variadic_sentinel : ?fails_on_nil:bool -> int -> int * int -> Builtin.t val check_variadic_sentinel : ?fails_on_nil:bool -> int -> int * int -> Builtin.t

@ -299,7 +299,7 @@ let func_with_tainted_params =
let attrs_opt_get_annots = function let attrs_opt_get_annots = function
| Some attrs -> attrs.ProcAttributes.method_annotation | Some attrs -> attrs.ProcAttributes.method_annotation
| None -> Typ.method_annotation_empty | None -> Annot.Method.empty
(* TODO: return a taint kind *) (* TODO: return a taint kind *)
(** returns true if [callee_pname] returns a tainted value *) (** returns true if [callee_pname] returns a tainted value *)

@ -13,12 +13,12 @@ module F = Format
module L = Logging module L = Logging
module CallSiteSet = AbstractDomain.FiniteSet (CallSite.Set) module CallSiteSet = AbstractDomain.FiniteSet (CallSite.Set)
module CallsDomain = AbstractDomain.Map (Typ.AnnotMap) (CallSiteSet) module CallsDomain = AbstractDomain.Map (Annot.Map) (CallSiteSet)
let dummy_constructor_annot = "__infer_is_constructor" let dummy_constructor_annot = "__infer_is_constructor"
let annotation_of_str annot_str = let annotation_of_str annot_str =
{ Typ.class_name = annot_str; parameters = []; } { Annot.class_name = annot_str; parameters = []; }
(* TODO: read custom source/sink pairs from user code here *) (* TODO: read custom source/sink pairs from user code here *)
let src_snk_pairs () = let src_snk_pairs () =
@ -161,7 +161,7 @@ let method_overrides is_annotated tenv pname =
overrides () overrides ()
let method_has_annot annot tenv pname = let method_has_annot annot tenv pname =
let has_annot ia = Annotations.ia_ends_with ia annot.Typ.class_name in let has_annot ia = Annotations.ia_ends_with ia annot.Annot.class_name in
if Annotations.annot_ends_with annot dummy_constructor_annot if Annotations.annot_ends_with annot dummy_constructor_annot
then is_allocator tenv pname then is_allocator tenv pname
else if Annotations.annot_ends_with annot Annotations.expensive else if Annotations.annot_ends_with annot Annotations.expensive
@ -176,7 +176,7 @@ let lookup_annotation_calls annot pname : CallSite.t list =
| Some { Specs.payload = { Specs.calls = Some call_map; }; } -> | Some { Specs.payload = { Specs.calls = Some call_map; }; } ->
begin begin
try try
Typ.AnnotMap.find annot call_map Annot.Map.find annot call_map
|> CallSiteSet.elements |> CallSiteSet.elements
with Not_found -> with Not_found ->
[] []
@ -303,14 +303,14 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(* TODO: generalize this to allow sanitizers for other annotation types, store it in [extras] so (* TODO: generalize this to allow sanitizers for other annotation types, store it in [extras] so
we can compute it just once *) we can compute it just once *)
let method_is_sanitizer annot tenv pname = let method_is_sanitizer annot tenv pname =
if annot.Typ.class_name = dummy_constructor_annot if annot.Annot.class_name = dummy_constructor_annot
then method_has_ignore_allocation_annot tenv pname then method_has_ignore_allocation_annot tenv pname
else false else false
let add_call call_map tenv callee_pname caller_pname call_site astate = let add_call call_map tenv callee_pname caller_pname call_site astate =
let add_call_for_annot annot _ astate = let add_call_for_annot annot _ astate =
let calls = let calls =
try Typ.AnnotMap.find annot call_map try Annot.Map.find annot call_map
with Not_found -> CallSiteSet.empty in with Not_found -> CallSiteSet.empty in
if (not (CallSiteSet.is_empty calls) || method_has_annot annot tenv callee_pname) && if (not (CallSiteSet.is_empty calls) || method_has_annot annot tenv callee_pname) &&
(not (method_is_sanitizer annot tenv caller_pname)) (not (method_is_sanitizer annot tenv caller_pname))
@ -323,7 +323,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Domain.NonBottom (map, _) -> | Domain.NonBottom (map, _) ->
(* for each annotation type T in domain(astate), check if method calls something annotated (* for each annotation type T in domain(astate), check if method calls something annotated
with T *) with T *)
Typ.AnnotMap.fold add_call_for_annot map astate Annot.Map.fold add_call_for_annot map astate
let exec_instr astate { ProcData.pdesc; tenv; } _ = function let exec_instr astate { ProcData.pdesc; tenv; } _ = function
| Sil.Call ([id], Const (Cfun callee_pname), _, _, _) | Sil.Call ([id], Const (Cfun callee_pname), _, _, _)
@ -338,7 +338,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
| Some Domain.NonBottom (call_map, _) -> | Some Domain.NonBottom (call_map, _) ->
add_call call_map tenv callee_pname caller_pname call_site astate add_call call_map tenv callee_pname caller_pname call_site astate
| None -> | None ->
add_call Typ.AnnotMap.empty tenv callee_pname caller_pname call_site astate add_call Annot.Map.empty tenv callee_pname caller_pname call_site astate
| Some Domain.Bottom -> | Some Domain.Bottom ->
astate astate
end end
@ -395,17 +395,17 @@ module Interprocedural = struct
PatternMatch.proc_iter_overridden_methods PatternMatch.proc_iter_overridden_methods
check_expensive_subtyping_rules tenv proc_name; check_expensive_subtyping_rules tenv proc_name;
let report_src_snk_paths call_map (src_annot_list, snk_annot) = let report_src_snk_paths call_map (src_annot_list, (snk_annot: Annot.t)) =
let extract_calls_with_annot annot call_map = let extract_calls_with_annot annot call_map =
try try
Typ.AnnotMap.find annot call_map Annot.Map.find annot call_map
|> CallSiteSet.elements |> CallSiteSet.elements
with Not_found -> [] in with Not_found -> [] in
let report_src_snk_path (calls : CallSite.t list) src_annot = let report_src_snk_path (calls : CallSite.t list) (src_annot: Annot.t) =
if method_overrides_annot src_annot tenv proc_name if method_overrides_annot src_annot tenv proc_name
then then
let f_report = let f_report =
report_annotation_stack src_annot.Typ.class_name snk_annot.Typ.class_name in report_annotation_stack src_annot.class_name snk_annot.class_name in
report_call_stack report_call_stack
(method_has_annot snk_annot tenv) (method_has_annot snk_annot tenv)
(lookup_annotation_calls snk_annot) (lookup_annotation_calls snk_annot)

@ -16,19 +16,19 @@ module L = Logging
(** Method signature with annotations. *) (** Method signature with annotations. *)
type annotated_signature = { type annotated_signature = {
ret : Typ.item_annotation * Typ.t; (** Annotated return type. *) ret : Annot.Item.t * Typ.t; (** Annotated return type. *)
params: (Mangled.t * Typ.item_annotation * Typ.t) list (** Annotated parameters. *) params: (Mangled.t * Annot.Item.t * Typ.t) list (** Annotated parameters. *)
} }
let param_equal (s1, ia1, t1) (s2, ia2, t2) = let param_equal (s1, ia1, t1) (s2, ia2, t2) =
Mangled.equal s1 s2 && Mangled.equal s1 s2 &&
Typ.item_annotation_compare ia1 ia2 = 0 && Annot.Item.compare ia1 ia2 = 0 &&
Typ.equal t1 t2 Typ.equal t1 t2
let equal as1 as2 = let equal as1 as2 =
let ia1, t1 = as1.ret let ia1, t1 = as1.ret
and ia2, t2 = as2.ret in and ia2, t2 = as2.ret in
Typ.item_annotation_compare ia1 ia2 = 0 && Annot.Item.compare ia1 ia2 = 0 &&
Typ.equal t1 t2 && Typ.equal t1 t2 &&
IList.for_all2 param_equal as1.params as2.params IList.for_all2 param_equal as1.params as2.params
@ -39,12 +39,12 @@ let ia_iter f =
let ann_iter (a, _) = f a in let ann_iter (a, _) = f a in
IList.iter ann_iter IList.iter ann_iter
let ma_iter f ((ia, ial) : Typ.method_annotation) = let ma_iter f ((ia, ial) : Annot.Method.t) =
IList.iter (ia_iter f) (ia:: ial) IList.iter (ia_iter f) (ia:: ial)
let ma_has_annotation_with let ma_has_annotation_with
(ma: Typ.method_annotation) (ma: Annot.Method.t)
(predicate: Typ.annotation -> bool): bool = (predicate: Annot.t -> bool): bool =
let found = ref false in let found = ref false in
ma_iter ma_iter
(fun a -> if predicate a then found := true) (fun a -> if predicate a then found := true)
@ -52,8 +52,8 @@ let ma_has_annotation_with
!found !found
let ia_has_annotation_with let ia_has_annotation_with
(ia: Typ.item_annotation) (ia: Annot.Item.t)
(predicate: Typ.annotation -> bool): bool = (predicate: Annot.t -> bool): bool =
let found = ref false in let found = ref false in
ia_iter ia_iter
(fun a -> if predicate a then found := true) (fun a -> if predicate a then found := true)
@ -66,7 +66,7 @@ let annot_ends_with annot ann_name =
let sl = String.length s in let sl = String.length s in
let al = String.length ann_name in let al = String.length ann_name in
sl >= al && String.sub s (sl - al) al = ann_name in sl >= al && String.sub s (sl - al) al = ann_name in
filter annot.Typ.class_name filter annot.Annot.class_name
(** Check if there is an annotation in [ia] which ends with the given name *) (** Check if there is an annotation in [ia] which ends with the given name *)
let ia_ends_with ia ann_name = let ia_ends_with ia ann_name =
@ -76,18 +76,18 @@ let ia_ends_with ia ann_name =
let ia_contains ia ann_name = let ia_contains ia ann_name =
let found = ref false in let found = ref false in
ia_iter (fun a -> if ann_name = a.Typ.class_name then found := true) ia; ia_iter (fun a -> if ann_name = a.Annot.class_name then found := true) ia;
!found !found
let ia_get ia ann_name = let ia_get ia ann_name =
let found = ref None in let found = ref None in
ia_iter (fun a -> if ann_name = a.Typ.class_name then found := Some a) ia; ia_iter (fun a -> if ann_name = a.Annot.class_name then found := Some a) ia;
!found !found
let ma_contains ma ann_names = let ma_contains ma ann_names =
let found = ref false in let found = ref false in
ma_iter (fun a -> ma_iter (fun a ->
if IList.exists (string_equal a.Typ.class_name) ann_names then found := true if IList.exists (string_equal a.Annot.class_name) ann_names then found := true
) ma; ) ma;
!found !found
@ -236,7 +236,7 @@ let get_annotated_signature proc_attributes : annotated_signature =
| ia :: ial', (name, typ) :: parl' -> | ia :: ial', (name, typ) :: parl' ->
(name, ia, typ) :: extract ial' parl' (name, ia, typ) :: extract ial' parl'
| [], (name, typ) :: parl' -> | [], (name, typ) :: parl' ->
(name, Typ.item_annotation_empty, typ) :: extract [] parl' (name, Annot.Item.empty, typ) :: extract [] parl'
| [], [] -> | [], [] ->
[] []
| _ :: _, [] -> | _ :: _, [] ->
@ -251,7 +251,7 @@ let get_annotated_signature proc_attributes : annotated_signature =
are called x0, x1, x2. *) are called x0, x1, x2. *)
let annotated_signature_is_anonymous_inner_class_wrapper ann_sig proc_name = let annotated_signature_is_anonymous_inner_class_wrapper ann_sig proc_name =
let check_ret (ia, t) = let check_ret (ia, t) =
Typ.item_annotation_is_empty ia && PatternMatch.type_is_object t in Annot.Item.is_empty ia && PatternMatch.type_is_object t in
let x_param_found = ref false in let x_param_found = ref false in
let name_is_x_number name = let name_is_x_number name =
let name_str = Mangled.to_string name in let name_str = Mangled.to_string name in
@ -270,7 +270,7 @@ let annotated_signature_is_anonymous_inner_class_wrapper ann_sig proc_name =
if Mangled.to_string name = "this" then true if Mangled.to_string name = "this" then true
else else
name_is_x_number name && name_is_x_number name &&
Typ.item_annotation_is_empty ia && Annot.Item.is_empty ia &&
PatternMatch.type_is_object t in PatternMatch.type_is_object t in
Procname.java_is_anonymous_inner_class proc_name Procname.java_is_anonymous_inner_class proc_name
&& check_ret ann_sig.ret && check_ret ann_sig.ret
@ -286,7 +286,7 @@ let param_is_nullable pvar ann_sig =
(** Pretty print a method signature with annotations. *) (** Pretty print a method signature with annotations. *)
let pp_annotated_signature proc_name fmt annotated_signature = let pp_annotated_signature proc_name fmt annotated_signature =
let pp_ia fmt ia = if ia <> [] then F.fprintf fmt "%a " Typ.pp_item_annotation ia in let pp_ia fmt ia = if ia <> [] then F.fprintf fmt "%a " Annot.Item.pp ia in
let pp_annotated_param fmt (p, ia, t) = let pp_annotated_param fmt (p, ia, t) =
F.fprintf fmt " %a%a %a" pp_ia ia (Typ.pp_full pe_text) t Mangled.pp p in F.fprintf fmt " %a%a %a" pp_ia ia (Typ.pp_full pe_text) t Mangled.pp p in
let ia, ret_type = annotated_signature.ret in let ia, ret_type = annotated_signature.ret in
@ -296,7 +296,7 @@ let pp_annotated_signature proc_name fmt annotated_signature =
(Procname.to_simplified_string proc_name) (Procname.to_simplified_string proc_name)
(pp_comma_seq pp_annotated_param) annotated_signature.params (pp_comma_seq pp_annotated_param) annotated_signature.params
let mk_ann_str s = { Typ.class_name = s; Typ.parameters = [] } let mk_ann_str s = { Annot.class_name = s; parameters = [] }
let mk_ann = function let mk_ann = function
| Nullable -> mk_ann_str nullable | Nullable -> mk_ann_str nullable
| Present -> mk_ann_str present | Present -> mk_ann_str present

@ -25,8 +25,8 @@ type annotation =
(** Method signature with annotations. *) (** Method signature with annotations. *)
type annotated_signature = { type annotated_signature = {
ret : Typ.item_annotation * Typ.t; (** Annotated return type. *) ret : Annot.Item.t * Typ.t; (** Annotated return type. *)
params: (Mangled.t * Typ.item_annotation * Typ.t) list (** Annotated parameters. *) params: (Mangled.t * Annot.Item.t * Typ.t) list (** Annotated parameters. *)
} }
(** Check if the annotated signature is for a wrapper of an anonymous inner class method. (** Check if the annotated signature is for a wrapper of an anonymous inner class method.
@ -57,57 +57,57 @@ val get_annotated_signature : ProcAttributes.t -> annotated_signature
val nullable : string val nullable : string
(** Return true if [annot] ends with [ann_name] *) (** Return true if [annot] ends with [ann_name] *)
val annot_ends_with : Typ.annotation -> string -> bool val annot_ends_with : Annot.t -> string -> bool
(** Check if there is an annotation in [ia] which ends with the given name *) (** Check if there is an annotation in [ia] which ends with the given name *)
val ia_ends_with : Typ.item_annotation -> string -> bool val ia_ends_with : Annot.Item.t -> string -> bool
val ia_contains : Typ.item_annotation -> string -> bool val ia_contains : Annot.Item.t -> string -> bool
val ia_has_annotation_with : Typ.item_annotation -> (Typ.annotation -> bool) -> bool val ia_has_annotation_with : Annot.Item.t -> (Annot.t -> bool) -> bool
val ia_get_strict : Typ.item_annotation -> Typ.annotation option val ia_get_strict : Annot.Item.t -> Annot.t option
val ia_is_false_on_null : Typ.item_annotation -> bool val ia_is_false_on_null : Annot.Item.t -> bool
val ia_is_initializer : Typ.item_annotation -> bool val ia_is_initializer : Annot.Item.t -> bool
(** Annotations for readonly injectors. (** Annotations for readonly injectors.
The injector framework initializes the field but does not write null into it. *) The injector framework initializes the field but does not write null into it. *)
val ia_is_field_injector_readonly : Typ.item_annotation -> bool val ia_is_field_injector_readonly : Annot.Item.t -> bool
(** Annotations for read-write injectors. (** Annotations for read-write injectors.
The injector framework initializes the field and can write null into it. *) The injector framework initializes the field and can write null into it. *)
val ia_is_field_injector_readwrite : Typ.item_annotation -> bool val ia_is_field_injector_readwrite : Annot.Item.t -> bool
val ia_is_mutable : Typ.item_annotation -> bool val ia_is_mutable : Annot.Item.t -> bool
val ia_is_nonnull : Typ.item_annotation -> bool val ia_is_nonnull : Annot.Item.t -> bool
val ia_is_nullable : Typ.item_annotation -> bool val ia_is_nullable : Annot.Item.t -> bool
val ia_is_present : Typ.item_annotation -> bool val ia_is_present : Annot.Item.t -> bool
val ia_is_true_on_null : Typ.item_annotation -> bool val ia_is_true_on_null : Annot.Item.t -> bool
val ia_is_verify : Typ.item_annotation -> bool val ia_is_verify : Annot.Item.t -> bool
val ia_is_expensive : Typ.item_annotation -> bool val ia_is_expensive : Annot.Item.t -> bool
val ia_is_performance_critical : Typ.item_annotation -> bool val ia_is_performance_critical : Annot.Item.t -> bool
val ia_is_no_allocation : Typ.item_annotation -> bool val ia_is_no_allocation : Annot.Item.t -> bool
val ia_is_ignore_allocations : Typ.item_annotation -> bool val ia_is_ignore_allocations : Annot.Item.t -> bool
val ia_is_suppress_warnings : Typ.item_annotation -> bool val ia_is_suppress_warnings : Annot.Item.t -> bool
val ia_is_privacy_source : Typ.item_annotation -> bool val ia_is_privacy_source : Annot.Item.t -> bool
val ia_is_privacy_sink : Typ.item_annotation -> bool val ia_is_privacy_sink : Annot.Item.t -> bool
val ia_is_integrity_source : Typ.item_annotation -> bool val ia_is_integrity_source : Annot.Item.t -> bool
val ia_is_integrity_sink : Typ.item_annotation -> bool val ia_is_integrity_sink : Annot.Item.t -> bool
val ia_is_guarded_by : Typ.item_annotation -> bool val ia_is_guarded_by : Annot.Item.t -> bool
val ia_iter : (Typ.annotation -> unit) -> Typ.item_annotation -> unit val ia_iter : (Annot.t -> unit) -> Annot.Item.t -> unit
val ma_has_annotation_with : Typ.method_annotation -> (Typ.annotation -> bool) -> bool val ma_has_annotation_with : Annot.Method.t -> (Annot.t -> bool) -> bool
val pdesc_has_annot : Cfg.Procdesc.t -> string -> bool val pdesc_has_annot : Cfg.Procdesc.t -> string -> bool
(** Mark the return of the method_annotation with the given annotation. *) (** Mark the return of the method_annotation with the given annotation. *)
val method_annotation_mark_return : val method_annotation_mark_return :
annotation -> Typ.method_annotation -> Typ.method_annotation annotation -> Annot.Method.t -> Annot.Method.t
(** Add the annotation to the item_annotation. *) (** Add the annotation to the item_annotation. *)
val mk_ia : annotation -> Typ.item_annotation -> Typ.item_annotation val mk_ia : annotation -> Annot.Item.t -> Annot.Item.t
val pp_annotated_signature : Procname.t -> Format.formatter -> annotated_signature -> unit val pp_annotated_signature : Procname.t -> Format.formatter -> annotated_signature -> unit

@ -89,7 +89,7 @@ module ST = struct
- @some.PrefixErrorName - @some.PrefixErrorName
where the kind matching is case - insensitive and ignores '-' and '_' characters. *) where the kind matching is case - insensitive and ignores '-' and '_' characters. *)
let suppressed = let suppressed =
let annotation_matches a = let annotation_matches (a: Annot.t) =
let normalize str = let normalize str =
Str.global_replace (Str.regexp "[_-]") "" (String.lowercase str) in Str.global_replace (Str.regexp "[_-]") "" (String.lowercase str) in
let drop_prefix str = let drop_prefix str =
@ -98,10 +98,10 @@ module ST = struct
string_equal (normalize s1) (normalize s2) in string_equal (normalize s1) (normalize s2) in
let is_parameter_suppressed = let is_parameter_suppressed =
IList.mem string_equal a.Typ.class_name [Annotations.suppressLint] && IList.mem string_equal a.class_name [Annotations.suppressLint] &&
IList.mem normalized_equal kind a.Typ.parameters in IList.mem normalized_equal kind a.parameters in
let is_annotation_suppressed = let is_annotation_suppressed =
string_is_suffix (normalize (drop_prefix kind)) (normalize a.Typ.class_name) in string_is_suffix (normalize (drop_prefix kind)) (normalize a.class_name) in
is_parameter_suppressed || is_annotation_suppressed in is_parameter_suppressed || is_annotation_suppressed in

@ -77,7 +77,7 @@ let type_get_class_name = function
| Typ.Tptr (typ, _) -> Typ.name typ | Typ.Tptr (typ, _) -> Typ.name typ
| _ -> None | _ -> None
let type_get_annotation tenv (typ: Typ.t): Typ.item_annotation option = let type_get_annotation tenv (typ: Typ.t): Annot.Item.t option =
match typ with match typ with
| Tptr (Tstruct name, _) | Tptr (Tstruct name, _)
| Tstruct name -> ( | Tstruct name -> (

@ -81,7 +81,7 @@ val proc_calls :
Only Java supported at the moment. *) Only Java supported at the moment. *)
val proc_iter_overridden_methods : (Procname.t -> unit) -> Tenv.t -> Procname.t -> unit val proc_iter_overridden_methods : (Procname.t -> unit) -> Tenv.t -> Procname.t -> unit
val type_get_annotation : Tenv.t -> Typ.t -> Typ.item_annotation option val type_get_annotation : Tenv.t -> Typ.t -> Annot.Item.t option
(** Get the class name of the type *) (** Get the class name of the type *)
val type_get_class_name : Typ.t -> Typename.t option val type_get_class_name : Typ.t -> Typename.t option

@ -15,7 +15,7 @@ open CFrontend_utils
module L = Logging module L = Logging
type field_type = Ident.fieldname * Typ.t * (Typ.annotation * bool) list type field_type = Ident.fieldname * Typ.t * (Annot.t * bool) list
let rec get_fields_super_classes tenv super_class = let rec get_fields_super_classes tenv super_class =
Printing.log_out " ... Getting fields of superclass '%s'\n" (Typename.to_string super_class); Printing.log_out " ... Getting fields of superclass '%s'\n" (Typename.to_string super_class);
@ -47,9 +47,11 @@ let build_sil_field type_ptr_to_sil_type tenv field_name type_ptr prop_attribute
let typ = type_ptr_to_sil_type tenv type_ptr in let typ = type_ptr_to_sil_type tenv type_ptr in
let item_annotations = match prop_atts with let item_annotations = match prop_atts with
| [] -> | [] ->
[({ Typ.class_name = Config.ivar_attributes; parameters = annotation_from_type typ }, true)] [({ Annot.class_name = Config.ivar_attributes; parameters = annotation_from_type typ },
true)]
| _ -> | _ ->
[({ Typ.class_name = Config.property_attributes; parameters = prop_atts }, true)] in [({ Annot.class_name = Config.property_attributes; parameters = prop_atts },
true)] in
fname, typ, item_annotations fname, typ, item_annotations
(* Given a list of declarations in an interface returns a list of fields *) (* Given a list of declarations in an interface returns a list of fields *)
@ -94,6 +96,6 @@ let modelled_field class_name_info =
let class_name_qualified = class_name_info.Clang_ast_t.ni_qual_name in let class_name_qualified = class_name_info.Clang_ast_t.ni_qual_name in
let field_name_qualified = Ast_utils.make_qual_name_decl class_name_qualified field_name in let field_name_qualified = Ast_utils.make_qual_name_decl class_name_qualified field_name in
let name = General_utils.mk_class_field_name field_name_qualified in let name = General_utils.mk_class_field_name field_name_qualified in
(name, typ, Typ.item_annotation_empty) :: res (name, typ, Annot.Item.empty) :: res
else res in else res in
IList.fold_left modelled_field_in_class [] modelled_fields_in_classes IList.fold_left modelled_field_in_class [] modelled_fields_in_classes

@ -12,7 +12,7 @@ open! Utils
(** Utility module to retrieve fields of structs of classes *) (** Utility module to retrieve fields of structs of classes *)
open CFrontend_utils open CFrontend_utils
type field_type = Ident.fieldname * Typ.t * (Typ.annotation * bool) list type field_type = Ident.fieldname * Typ.t * (Annot.t * bool) list
val get_fields : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> CContext.curr_class -> val get_fields : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> CContext.curr_class ->
Clang_ast_t.decl list -> field_type list Clang_ast_t.decl list -> field_type list

@ -494,7 +494,7 @@ struct
let append_no_duplicates_annotations list1 list2 = let append_no_duplicates_annotations list1 list2 =
let eq (annot1, _) (annot2, _) = annot1.Typ.class_name = annot2.Typ.class_name in let eq (annot1, _) (annot2, _) = annot1.Annot.class_name = annot2.Annot.class_name in
append_no_duplicates eq list1 list2 append_no_duplicates eq list1 list2
let add_no_duplicates_fields field_tuple l = let add_no_duplicates_fields field_tuple l =

@ -163,9 +163,9 @@ sig
val string_from_list : string list -> string val string_from_list : string list -> string
val append_no_duplicates_fields : (Ident.fieldname * Typ.t * Typ.item_annotation) list -> val append_no_duplicates_fields : (Ident.fieldname * Typ.t * Annot.Item.t) list ->
(Ident.fieldname * Typ.t * Typ.item_annotation) list -> (Ident.fieldname * Typ.t * Annot.Item.t) list ->
(Ident.fieldname * Typ.t * Typ.item_annotation) list (Ident.fieldname * Typ.t * Annot.Item.t) list
val append_no_duplicates_csu : val append_no_duplicates_csu :
Typename.t list -> Typename.t list -> Typename.t list Typename.t list -> Typename.t list -> Typename.t list
@ -179,8 +179,8 @@ sig
(Exp.t * Typ.t) list -> (Exp.t * Typ.t) list -> (Exp.t * Typ.t) list (Exp.t * Typ.t) list -> (Exp.t * Typ.t) list -> (Exp.t * Typ.t) list
val sort_fields : val sort_fields :
(Ident.fieldname * Typ.t * Typ.item_annotation) list -> (Ident.fieldname * Typ.t * Annot.Item.t) list ->
(Ident.fieldname * Typ.t * Typ.item_annotation) list (Ident.fieldname * Typ.t * Annot.Item.t) list
val sort_fields_tenv : Tenv.t -> unit val sort_fields_tenv : Tenv.t -> unit

@ -336,16 +336,16 @@ let should_create_procdesc cfg procname defined =
else false else false
| None -> true | None -> true
let sil_method_annotation_of_args args : Typ.method_annotation = let sil_method_annotation_of_args args : Annot.Method.t =
let default_visibility = true in let default_visibility = true in
let mk_annot param_name annot_name = let mk_annot param_name annot_name =
let annot = { Typ.class_name = annot_name; Typ.parameters = [param_name]; } in let annot = { Annot.class_name = annot_name; parameters = [param_name]; } in
annot, default_visibility in annot, default_visibility in
let arg_to_sil_annot (arg_mangled, {Clang_ast_t.qt_type_ptr}) acc = let arg_to_sil_annot (arg_mangled, {Clang_ast_t.qt_type_ptr}) acc =
let arg_name = Mangled.to_string arg_mangled in let arg_name = Mangled.to_string arg_mangled in
if CFrontend_utils.Ast_utils.is_type_nullable qt_type_ptr then if CFrontend_utils.Ast_utils.is_type_nullable qt_type_ptr then
[mk_annot arg_name Annotations.nullable] :: acc [mk_annot arg_name Annotations.nullable] :: acc
else Typ.item_annotation_empty::acc in else Annot.Item.empty::acc in
let param_annots = IList.fold_right arg_to_sil_annot args [] in let param_annots = IList.fold_right arg_to_sil_annot args [] in
(* TODO: parse annotations on return value *) (* TODO: parse annotations on return value *)
let retval_annot = [] in let retval_annot = [] in

@ -118,7 +118,7 @@ struct
let vname = Pvar.get_name var in let vname = Pvar.get_name var in
let qual_name = Ast_utils.make_qual_name_decl [block_name] (Mangled.to_string vname) in let qual_name = Ast_utils.make_qual_name_decl [block_name] (Mangled.to_string vname) in
let fname = General_utils.mk_class_field_name qual_name in let fname = General_utils.mk_class_field_name qual_name in
let item_annot = Typ.item_annotation_empty in let item_annot = Annot.Item.empty in
fname, typ, item_annot in fname, typ, item_annot in
let fields = IList.map mk_field_from_captured_var captured_vars in let fields = IList.map mk_field_from_captured_var captured_vars in
Printing.log_out "Block %s field:\n" block_name; Printing.log_out "Block %s field:\n" block_name;

@ -182,8 +182,8 @@ and get_record_declaration_struct_type tenv decl =
[Typ.objc_ref_counter_field] [Typ.objc_ref_counter_field]
else [] in else [] in
let annots = let annots =
if csu = Csu.Class Csu.CPP then Typ.cpp_class_annotation if csu = Csu.Class Csu.CPP then Annot.Class.cpp
else Typ.item_annotation_empty (* No annotations for structs *) in else Annot.Item.empty (* No annotations for structs *) in
if is_complete_definition then ( if is_complete_definition then (
Ast_utils.update_sil_types_map type_ptr (Typ.Tstruct sil_typename); Ast_utils.update_sil_types_map type_ptr (Typ.Tstruct sil_typename);
let non_statics = get_struct_fields tenv decl in let non_statics = get_struct_fields tenv decl in

@ -126,7 +126,7 @@ let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info name_info d
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) all_fields; Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) all_fields;
ignore( ignore(
Tenv.mk_struct tenv Tenv.mk_struct tenv
~fields: all_fields ~supers ~methods ~annots:Typ.objc_class_annotation interface_name ); ~fields: all_fields ~supers ~methods ~annots:Annot.Class.objc interface_name );
Printing.log_out Printing.log_out
" >>>Verifying that Typename '%s' is in tenv\n" (Typename.to_string interface_name); " >>>Verifying that Typename '%s' is in tenv\n" (Typename.to_string interface_name);
(match Tenv.lookup tenv interface_name with (match Tenv.lookup tenv interface_name with

@ -21,9 +21,9 @@ let log_err fmt =
pp Format.err_formatter fmt pp Format.err_formatter fmt
let annotation_to_string (annotation, _) = let annotation_to_string ((annotation: Annot.t), _) =
"< " ^ annotation.Typ.class_name ^ " : " ^ "< " ^ annotation.class_name ^ " : " ^
(IList.to_string (fun x -> x) annotation.Typ.parameters) ^ " >" (IList.to_string (fun x -> x) annotation.parameters) ^ " >"
let field_to_string (fieldname, typ, annotation) = let field_to_string (fieldname, typ, annotation) =
(Ident.fieldname_to_string fieldname) ^ " " ^ (Ident.fieldname_to_string fieldname) ^ " " ^
@ -41,7 +41,7 @@ let print_tenv tenv =
| Typename.TN_csu (Csu.Class _, _) | Typename.TN_csu (Csu.Protocol, _) -> | Typename.TN_csu (Csu.Class _, _) | Typename.TN_csu (Csu.Protocol, _) ->
print_endline ( print_endline (
(Typename.to_string typname) ^ " " ^ (Typename.to_string typname) ^ " " ^
(Typ.item_annotation_to_string struct_t.annots) ^ "\n" ^ (Annot.Item.to_string struct_t.annots) ^ "\n" ^
"---> superclass and protocols " ^ (IList.to_string (fun tn -> "---> superclass and protocols " ^ (IList.to_string (fun tn ->
"\t" ^ (Typename.to_string tn) ^ "\n") struct_t.supers) ^ "\t" ^ (Typename.to_string tn) ^ "\n") struct_t.supers) ^
"---> methods " ^ "---> methods " ^

@ -27,4 +27,4 @@ val print_nodes : Cfg.Node.t list -> unit
val instrs_to_string : Sil.instr list -> string val instrs_to_string : Sil.instr list -> string
val field_to_string : Ident.fieldname * Typ.t * Typ.item_annotation -> string val field_to_string : Ident.fieldname * Typ.t * Annot.Item.t -> string

@ -19,7 +19,7 @@ val const : Annotations.annotation -> bool -> TypeOrigin.t -> t
val descr_origin : Tenv.t -> t -> TypeErr.origin_descr val descr_origin : Tenv.t -> t -> TypeErr.origin_descr
val equal : t -> t -> bool val equal : t -> t -> bool
val from_item_annotation : Typ.item_annotation -> TypeOrigin.t -> t val from_item_annotation : Annot.Item.t -> TypeOrigin.t -> t
val get_origin : t -> TypeOrigin.t val get_origin : t -> TypeOrigin.t
val get_value : Annotations.annotation -> t -> bool val get_value : Annotations.annotation -> t -> bool
val join : t -> t -> t option val join : t -> t -> t option

@ -280,7 +280,7 @@ module Strict = struct
(* Return (Some parameters) if there is a method call on a @Nullable object,*) (* Return (Some parameters) if there is a method call on a @Nullable object,*)
(* where the origin of @Nullable in the analysis is the return value of a Strict method*) (* where the origin of @Nullable in the analysis is the return value of a Strict method*)
(* with parameters. A method is Strict if it or its class are annotated @Strict. *) (* with parameters. A method is Strict if it or its class are annotated @Strict. *)
let err_instance_get_strict tenv err_instance : Typ.annotation option = let err_instance_get_strict tenv err_instance : Annot.t option =
match err_instance with match err_instance with
| Call_receiver_annotation_inconsistent (Annotations.Nullable, _, _, origin_descr) | Call_receiver_annotation_inconsistent (Annotations.Nullable, _, _, origin_descr)
| Null_field_access (_, _, origin_descr, _) -> | Null_field_access (_, _, origin_descr, _) ->

@ -29,7 +29,8 @@ module InstrRef : InstrRefT
module Strict : module Strict :
sig sig
val signature_get_strict : Tenv.t -> Annotations.annotated_signature -> Typ.annotation option val signature_get_strict :
Tenv.t -> Annotations.annotated_signature -> Annot.t option
end (* Strict *) end (* Strict *)

@ -91,7 +91,7 @@ let get_description tenv origin =
let strict = match TypeErr.Strict.signature_get_strict tenv po.annotated_signature with let strict = match TypeErr.Strict.signature_get_strict tenv po.annotated_signature with
| Some ann -> | Some ann ->
let str = "@Strict" in let str = "@Strict" in
(match ann.Typ.parameters with (match ann.Annot.parameters with
| par1 :: _ -> Printf.sprintf "%s(%s) " str par1 | par1 :: _ -> Printf.sprintf "%s(%s) " str par1
| [] -> Printf.sprintf "%s " str) | [] -> Printf.sprintf "%s " str)
| None -> "" in | None -> "" in

@ -17,12 +17,13 @@ let is_suppress_warnings_annotated =
Inferconfig.suppress_warnings_matcher DB.source_file_empty Inferconfig.suppress_warnings_matcher DB.source_file_empty
let suppress_warnings = let suppress_warnings =
({ Typ.class_name = Annotations.suppress_warnings; ({ Annot.
Typ.parameters = ["infer"] }, class_name = Annotations.suppress_warnings;
parameters = ["infer"] },
true) true)
(** Translate an annotation. *) (** Translate an annotation. *)
let translate a : Typ.annotation = let translate a : Annot.t =
let class_name = JBasics.cn_name a.JBasics.kind in let class_name = JBasics.cn_name a.JBasics.kind in
let translate_value_pair (_, value) = let translate_value_pair (_, value) =
match value with match value with
@ -32,12 +33,13 @@ let translate a : Typ.annotation =
s s
| _ -> "?" in | _ -> "?" in
let element_value_pairs = a.JBasics.element_value_pairs in let element_value_pairs = a.JBasics.element_value_pairs in
{ Typ.class_name = class_name; { Annot.
Typ.parameters = IList.map translate_value_pair element_value_pairs } class_name;
parameters = IList.map translate_value_pair element_value_pairs }
(** Translate an item annotation. *) (** Translate an item annotation. *)
let translate_item avlist : Typ.item_annotation = let translate_item avlist : Annot.Item.t =
let trans_vis = function let trans_vis = function
| Javalib.RTVisible -> true | Javalib.RTVisible -> true
| Javalib.RTInvisible -> false in | Javalib.RTInvisible -> false in
@ -46,7 +48,7 @@ let translate_item avlist : Typ.item_annotation =
(** Translate a method annotation. *) (** Translate a method annotation. *)
let translate_method proc_name_java ann : Typ.method_annotation = let translate_method proc_name_java ann : Annot.Method.t =
let global_ann = ann.Javalib.ma_global in let global_ann = ann.Javalib.ma_global in
let param_ann = ann.Javalib.ma_parameters in let param_ann = ann.Javalib.ma_parameters in
let ret_item = let ret_item =

@ -14,7 +14,7 @@ open Javalib_pack
(** Translate an item annotation. *) (** Translate an item annotation. *)
val translate_item : (JBasics.annotation * Javalib.visibility) list -> Typ.item_annotation val translate_item : (JBasics.annotation * Javalib.visibility) list -> Annot.Item.t
(** Translate a method annotation. *) (** Translate a method annotation. *)
val translate_method : Procname.java -> Javalib.method_annotations -> Typ.method_annotation val translate_method : Procname.java -> Javalib.method_annotations -> Annot.Method.t

Loading…
Cancel
Save