Refactor Sil.typ into separate Typ module

Summary:
Now that array types record only static - and therefore constant -
lengths, Sil typ and exp no longer need to be mutually recursive.
This diff:
- splits the recursion in the type definitions of typ and exp,
- splits the recursion in the comparison and pretty-printing
  functions,
- and then refactors typ into a separate module.

Reviewed By: cristianoc

Differential Revision: D3423575

fbshipit-source-id: 6130630
master
Josh Berdine 9 years ago committed by Facebook Github Bot 7
parent ce19de4a42
commit bbec166174

@ -92,7 +92,7 @@ let get_correct_type_from_objc_class_name c => {
| None => None | None => None
| Some tenv => | Some tenv =>
let type_name = Typename.TN_csu (Csu.Class Csu.Objc) c; let type_name = Typename.TN_csu (Csu.Class Csu.Objc) c;
Option.map (fun st => Sil.Tstruct st) (Tenv.lookup tenv type_name) Option.map (fun st => Typ.Tstruct st) (Tenv.lookup tenv type_name)
} }
}; };

@ -30,7 +30,7 @@ let find_tenv_from_class_of_proc: Procname.t => option Tenv.t;
/** Given an ObjC class c, extract the type from the tenv where the class was */ /** Given an ObjC class c, extract the type from the tenv where the class was */
/** defined. We do this by adding a method that is unique to each class, and then */ /** defined. We do this by adding a method that is unique to each class, and then */
/** finding the tenv that corresponds to the class definition. */ /** finding the tenv that corresponds to the class definition. */
let get_correct_type_from_objc_class_name: Mangled.t => option Sil.typ; let get_correct_type_from_objc_class_name: Mangled.t => option Typ.t;
/** Returns true if the method is defined as a C++ model */ /** Returns true if the method is defined as a C++ model */

@ -92,7 +92,7 @@ let module Node = {
let id_map = ref IntMap.empty; let id_map = ref IntMap.empty;
/* formals are the same if their types are the same */ /* formals are the same if their types are the same */
let formals_eq formals1 formals2 => let formals_eq formals1 formals2 =>
IList.equal (fun (_, typ1) (_, typ2) => Sil.typ_compare typ1 typ2) formals1 formals2; IList.equal (fun (_, typ1) (_, typ2) => Typ.compare typ1 typ2) formals1 formals2;
let nodes_eq n1s n2s => let nodes_eq n1s n2s =>
/* nodes are the same if they have the same id, instructions, and succs/preds up to renaming /* nodes are the same if they have the same id, instructions, and succs/preds up to renaming
with [exp_map] and [id_map] */ with [exp_map] and [id_map] */
@ -133,7 +133,7 @@ let module Node = {
let att1 = pd1.pd_attributes let att1 = pd1.pd_attributes
and att2 = pd2.pd_attributes; and att2 = pd2.pd_attributes;
att1.ProcAttributes.is_defined == att2.ProcAttributes.is_defined && att1.ProcAttributes.is_defined == att2.ProcAttributes.is_defined &&
Sil.typ_equal att1.ProcAttributes.ret_type att2.ProcAttributes.ret_type && Typ.equal att1.ProcAttributes.ret_type att2.ProcAttributes.ret_type &&
formals_eq att1.ProcAttributes.formals att2.ProcAttributes.formals && formals_eq att1.ProcAttributes.formals att2.ProcAttributes.formals &&
nodes_eq pd1.pd_nodes pd2.pd_nodes nodes_eq pd1.pd_nodes pd2.pd_nodes
}; };
@ -660,7 +660,7 @@ let module Node = {
| exp => exp; | exp => exp;
let extract_class_name = let extract_class_name =
fun fun
| Sil.Tptr (Sil.Tstruct {Sil.struct_name: struct_name}) _ when struct_name != None => | Typ.Tptr (Typ.Tstruct {Typ.struct_name: struct_name}) _ when struct_name != None =>
Mangled.to_string (Option.get struct_name) Mangled.to_string (Option.get struct_name)
| _ => failwith "Expecting classname for Java types"; | _ => failwith "Expecting classname for Java types";
let subst_map = ref Ident.IdentMap.empty; let subst_map = ref Ident.IdentMap.empty;
@ -683,7 +683,7 @@ let module Node = {
| Sil.Letderef id (Sil.Var origin_id as origin_exp) origin_typ loc => { | Sil.Letderef id (Sil.Var origin_id as origin_exp) origin_typ loc => {
let updated_typ = let updated_typ =
switch (Ident.IdentMap.find origin_id !subst_map) { switch (Ident.IdentMap.find origin_id !subst_map) {
| Sil.Tptr typ _ => typ | Typ.Tptr typ _ => typ
| _ => failwith "Expecting a pointer type" | _ => failwith "Expecting a pointer type"
| exception Not_found => origin_typ | exception Not_found => origin_typ
}; };

@ -57,16 +57,16 @@ let module Procdesc: {
let get_flags: t => proc_flags; let get_flags: t => proc_flags;
/** Return name and type of formal parameters */ /** Return name and type of formal parameters */
let get_formals: t => list (Mangled.t, Sil.typ); let get_formals: t => list (Mangled.t, Typ.t);
/** Return loc information for the procedure */ /** Return loc information for the procedure */
let get_loc: t => Location.t; let get_loc: t => Location.t;
/** Return name and type of local variables */ /** Return name and type of local variables */
let get_locals: t => list (Mangled.t, Sil.typ); let get_locals: t => list (Mangled.t, Typ.t);
/** Return name and type of block's captured variables */ /** Return name and type of block's captured variables */
let get_captured: t => list (Mangled.t, Sil.typ); let get_captured: t => list (Mangled.t, Typ.t);
/** Return the visibility attribute */ /** Return the visibility attribute */
let get_access: t => Sil.access; let get_access: t => Sil.access;
@ -80,7 +80,7 @@ let module Procdesc: {
let get_proc_name: t => Procname.t; let get_proc_name: t => Procname.t;
/** Return the return type of the procedure and type string */ /** Return the return type of the procedure and type string */
let get_ret_type: t => Sil.typ; let get_ret_type: t => Typ.t;
let get_ret_var: t => Pvar.t; let get_ret_var: t => Pvar.t;
let get_start_node: t => node; let get_start_node: t => node;
@ -120,7 +120,7 @@ let module Procdesc: {
let set_start_node: t => node => unit; let set_start_node: t => node => unit;
/** append a list of new local variables to the existing list of local variables */ /** append a list of new local variables to the existing list of local variables */
let append_locals: t => list (Mangled.t, Sil.typ) => unit; let append_locals: t => list (Mangled.t, Typ.t) => unit;
}; };
@ -154,7 +154,7 @@ let module Node: {
let prepend_instrs: t => list Sil.instr => unit; let prepend_instrs: t => list Sil.instr => unit;
/** Add declarations for local variables and return variable to the node */ /** Add declarations for local variables and return variable to the node */
let add_locals_ret_declaration: t => list (Mangled.t, Sil.typ) => unit; let add_locals_ret_declaration: t => list (Mangled.t, Typ.t) => unit;
/** Compare two nodes */ /** Compare two nodes */
let compare: t => t => int; let compare: t => t => int;
@ -331,4 +331,4 @@ let remove_seed_captured_vars_block: list Mangled.t => Prop.t Prop.normal => Pro
(name, typ) where name is a parameter. The resulting procdesc is isomorphic but (name, typ) where name is a parameter. The resulting procdesc is isomorphic but
all the type of the parameters are replaced in the instructions according to the list. all the type of the parameters are replaced in the instructions according to the list.
The virtual calls are also replaced to match the parameter types */ The virtual calls are also replaced to match the parameter types */
let specialize_types: Procdesc.t => Procname.t => list (Sil.exp, Sil.typ) => Procdesc.t; let specialize_types: Procdesc.t => Procname.t => list (Sil.exp, Typ.t) => Procdesc.t;

@ -24,11 +24,11 @@ type objc_accessor_type = | Objc_getter of Ident.fieldname | Objc_setter of Iden
type t = { type t = {
access: Sil.access, /** visibility access */ access: Sil.access, /** visibility access */
captured: list (Mangled.t, Sil.typ), /** name and type of variables captured in blocks */ captured: list (Mangled.t, Typ.t), /** name and type of variables captured in blocks */
mutable changed: bool, /** true if proc has changed since last analysis */ mutable changed: bool, /** true if proc has changed since last analysis */
err_log: Errlog.t, /** Error log for the procedure */ err_log: Errlog.t, /** Error log for the procedure */
exceptions: list string, /** exceptions thrown by the procedure */ exceptions: list string, /** exceptions thrown by the procedure */
formals: list (Mangled.t, Sil.typ), /** name and type of formal parameters */ formals: list (Mangled.t, Typ.t), /** name and type of formal parameters */
func_attributes: list Sil.func_attribute, func_attributes: list Sil.func_attribute,
is_abstract: bool, /** the procedure is abstract */ is_abstract: bool, /** the procedure is abstract */
mutable is_bridge_method: bool, /** the procedure is a bridge method */ mutable is_bridge_method: bool, /** the procedure is a bridge method */
@ -39,12 +39,12 @@ type t = {
mutable is_synthetic_method: bool, /** the procedure is a synthetic method */ mutable is_synthetic_method: bool, /** the procedure is a synthetic method */
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, Sil.typ), /** name and type of local variables */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */
method_annotation: Sil.method_annotation, /** annotations for java methods */ method_annotation: Typ.method_annotation, /** 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 */
ret_type: Sil.typ /** return type */ ret_type: Typ.t /** return type */
}; };
let default proc_name language => { let default proc_name language => {
@ -65,9 +65,9 @@ let default proc_name language => {
language, language,
loc: Location.dummy, loc: Location.dummy,
locals: [], locals: [],
method_annotation: Sil.method_annotation_empty, method_annotation: Typ.method_annotation_empty,
objc_accessor: None, objc_accessor: None,
proc_flags: proc_flags_empty (), proc_flags: proc_flags_empty (),
proc_name, proc_name,
ret_type: Sil.Tvoid ret_type: Typ.Tvoid
}; };

@ -18,11 +18,11 @@ type objc_accessor_type = | Objc_getter of Ident.fieldname | Objc_setter of Iden
type t = { type t = {
access: Sil.access, /** visibility access */ access: Sil.access, /** visibility access */
captured: list (Mangled.t, Sil.typ), /** name and type of variables captured in blocks */ captured: list (Mangled.t, Typ.t), /** name and type of variables captured in blocks */
mutable changed: bool, /** true if proc has changed since last analysis */ mutable changed: bool, /** true if proc has changed since last analysis */
err_log: Errlog.t, /** Error log for the procedure */ err_log: Errlog.t, /** Error log for the procedure */
exceptions: list string, /** exceptions thrown by the procedure */ exceptions: list string, /** exceptions thrown by the procedure */
formals: list (Mangled.t, Sil.typ), /** name and type of formal parameters */ formals: list (Mangled.t, Typ.t), /** name and type of formal parameters */
func_attributes: list Sil.func_attribute, func_attributes: list Sil.func_attribute,
is_abstract: bool, /** the procedure is abstract */ is_abstract: bool, /** the procedure is abstract */
mutable is_bridge_method: bool, /** the procedure is a bridge method */ mutable is_bridge_method: bool, /** the procedure is a bridge method */
@ -33,12 +33,12 @@ type t = {
mutable is_synthetic_method: bool, /** the procedure is a synthetic method */ mutable is_synthetic_method: bool, /** the procedure is a synthetic method */
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, Sil.typ), /** name and type of local variables */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */
method_annotation: Sil.method_annotation, /** annotations for java methods */ method_annotation: Typ.method_annotation, /** 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 */
ret_type: Sil.typ /** return type */ ret_type: Typ.t /** return type */
}; };

File diff suppressed because it is too large Load Diff

@ -19,21 +19,6 @@ let module F = Format;
/** {2 Programs and Types} */ /** {2 Programs and Types} */
/** Type to represent one @Annotation. */
type annotation = {
class_name: string, /* name of the annotation */
parameters: list string
/* currently only one string parameter */
};
/** Annotation for one item: a list of annotations with visibility. */
type item_annotation = list (annotation, bool);
/** Annotation for a method: return value and list of parameters. */
type method_annotation = (item_annotation, list item_annotation);
type func_attribute = | FA_sentinel of int int; type func_attribute = | FA_sentinel of int int;
@ -74,31 +59,6 @@ type binop =
| PtrFld /** field offset via pointer to field: takes the address of a | PtrFld /** field offset via pointer to field: takes the address of a
Csu.t and a Cptr_to_fld constant to form an Lfield expression (see prop.ml) */; Csu.t and a Cptr_to_fld constant to form an Lfield expression (see prop.ml) */;
/** Kinds of integers */
type ikind =
| IChar /** [char] */
| ISChar /** [signed char] */
| IUChar /** [unsigned char] */
| IBool /** [bool] */
| IInt /** [int] */
| IUInt /** [unsigned int] */
| IShort /** [short] */
| IUShort /** [unsigned short] */
| ILong /** [long] */
| IULong /** [unsigned long] */
| ILongLong /** [long long] (or [_int64] on Microsoft Visual C) */
| IULongLong /** [unsigned long long] (or [unsigned _int64] on Microsoft Visual C) */
| I128 /** [__int128_t] */
| IU128 /** [__uint128_t] */;
/** Kinds of floating-point numbers*/
type fkind =
| FFloat /** [float] */
| FDouble /** [double] */
| FLongDouble /** [long double] */;
type mem_kind = type mem_kind =
| Mmalloc /** memory allocated with malloc */ | Mmalloc /** memory allocated with malloc */
| Mnew /** memory allocated with new */ | Mnew /** memory allocated with new */
@ -124,15 +84,6 @@ type dangling_kind =
| DAminusone; | DAminusone;
/** kind of pointer */
type ptr_kind =
| Pk_pointer /* C/C++, Java, Objc standard/__strong pointer*/
| Pk_reference /* C++ reference */
| Pk_objc_weak /* Obj-C __weak pointer*/
| Pk_objc_unsafe_unretained /* Obj-C __unsafe_unretained pointer */
| Pk_objc_autoreleasing /* Obj-C __autoreleasing pointer */;
/** position in a path: proc name, node id */ /** position in a path: proc name, node id */
type path_pos = (Procname.t, int); type path_pos = (Procname.t, int);
@ -181,13 +132,22 @@ type call_flags = {
/** Default value for call_flags where all fields are set to false */ /** Default value for call_flags where all fields are set to false */
let cf_default: call_flags; let cf_default: call_flags;
type taint_kind =
| Tk_unverified_SSL_socket
| Tk_shared_preferences_data
| Tk_privacy_annotation
| Tk_integrity_annotation
| Tk_unknown;
type taint_info = {taint_source: Procname.t, taint_kind: taint_kind};
/** expression representing the result of decompilation */ /** expression representing the result of decompilation */
type dexp = type dexp =
| Darray of dexp dexp | Darray of dexp dexp
| Dbinop of binop dexp dexp | Dbinop of binop dexp dexp
| Dconst of const | Dconst of const
| Dsizeof of typ (option exp) Subtype.t | Dsizeof of Typ.t (option exp) Subtype.t
| Dderef of dexp | Dderef of dexp
| Dfcall of dexp (list dexp) Location.t call_flags | Dfcall of dexp (list dexp) Location.t call_flags
| Darrow of dexp Ident.fieldname | Darrow of dexp Ident.fieldname
@ -208,20 +168,13 @@ and res_action = {
ra_loc: Location.t, /** location of the acquire/release */ ra_loc: Location.t, /** location of the acquire/release */
ra_vpath: vpath /** vpath of the resource value */ ra_vpath: vpath /** vpath of the resource value */
} }
and taint_kind =
| Tk_unverified_SSL_socket
| Tk_shared_preferences_data
| Tk_privacy_annotation
| Tk_integrity_annotation
| Tk_unknown
and taint_info = {taint_source: Procname.t, taint_kind: taint_kind}
/** Attributes */ /** Attributes */
and attribute = and attribute =
| Aresource of res_action /** resource acquire/release */ | Aresource of res_action /** resource acquire/release */
| Aautorelease | Aautorelease
| Adangling of dangling_kind /** dangling pointer */ | Adangling of dangling_kind /** dangling pointer */
/** undefined value obtained by calling the given procedure */ /** undefined value obtained by calling the given procedure, plus its return value annots */
| Aundef of Procname.t item_annotation Location.t path_pos | Aundef of Procname.t Typ.item_annotation Location.t path_pos
| Ataint of taint_info | Ataint of taint_info
| Auntaint of taint_info | Auntaint of taint_info
| Alocked | Alocked
@ -230,24 +183,13 @@ and attribute =
| Adiv0 of path_pos | Adiv0 of path_pos
/** the exp. is null because of a call to a method with exp as a null receiver */ /** the exp. is null because of a call to a method with exp as a null receiver */
| Aobjc_null of exp | Aobjc_null of exp
/** value was returned from a call to the given procedure */ /** value was returned from a call to the given procedure, plus the annots of the return value */
| Aretval of Procname.t item_annotation | Aretval of Procname.t Typ.item_annotation
/** 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 */
| Aunsubscribed_observer | Aunsubscribed_observer
/** Categories of attributes */ and closure = {name: Procname.t, captured_vars: list (exp, Pvar.t, Typ.t)}
and attribute_category =
| ACresource
| ACautorelease
| ACtaint
| AClock
| ACdiv0
| ACobjc_null
| ACundef
| ACretval
| ACobserver
and closure = {name: Procname.t, captured_vars: list (exp, Pvar.t, typ)}
/** Constants */ /** Constants */
and const = and const =
| Cint of IntLit.t /** integer constants */ | Cint of IntLit.t /** integer constants */
@ -257,90 +199,35 @@ and const =
| Cattribute of attribute /** attribute used in disequalities to annotate a value */ | Cattribute of attribute /** attribute used in disequalities to annotate a value */
| Cexn of exp /** exception */ | Cexn of exp /** exception */
| Cclass of Ident.name /** class constant */ | Cclass of Ident.name /** class constant */
| Cptr_to_fld of Ident.fieldname typ /** pointer to field constant, | Cptr_to_fld of Ident.fieldname Typ.t /** pointer to field constant,
and type of the surrounding Csu.t type */ and type of the surrounding Csu.t type */
| Cclosure of closure /** anonymous function */ | Cclosure of closure /** anonymous function */
and struct_fields = list (Ident.fieldname, typ, item_annotation)
/** Type for a structured value. */
and struct_typ = {
instance_fields: struct_fields, /** non-static fields */
static_fields: struct_fields, /** static fields */
csu: Csu.t, /** class/struct/union */
struct_name: option Mangled.t, /** name */
superclasses: list Typename.t, /** list of superclasses */
def_methods: list Procname.t, /** methods defined */
struct_annotations: item_annotation /** annotations */
}
/** statically determined length of an array type, if any */
and static_length = option IntLit.t
/** dynamically determined length of an array value, if any */ /** dynamically determined length of an array value, if any */
and dynamic_length = option exp and dynamic_length = option exp
/** Types for sil (structured) expressions. */
and typ =
| Tvar of Typename.t /** named type */
| Tint of ikind /** integer type */
| Tfloat of fkind /** float type */
| Tvoid /** void type */
| Tfun of bool /** function type with noreturn attribute */
| Tptr of typ ptr_kind /** pointer type */
| Tstruct of struct_typ /** Type for a structured value */
| Tarray of typ static_length /** array type with statically fixed length */
/** Program expressions. */ /** Program expressions. */
and exp = and exp =
/** Pure variable: it is not an lvalue */ /** Pure variable: it is not an lvalue */
| Var of Ident.t | Var of Ident.t
/** Unary operator with type of the result if known */ /** Unary operator with type of the result if known */
| UnOp of unop exp (option typ) | UnOp of unop exp (option Typ.t)
/** Binary operator */ /** Binary operator */
| BinOp of binop exp exp | BinOp of binop exp exp
/** Constants */ /** Constants */
| Const of const | Const of const
/** Type cast */ /** Type cast */
| Cast of typ exp | Cast of Typ.t exp
/** The address of a program variable */ /** The address of a program variable */
| Lvar of Pvar.t | Lvar of Pvar.t
/** A field offset, the type is the surrounding struct type */ /** A field offset, the type is the surrounding struct type */
| Lfield of exp Ident.fieldname typ | Lfield of exp Ident.fieldname Typ.t
/** An array index offset: [exp1\[exp2\]] */ /** An array index offset: [exp1\[exp2\]] */
| Lindex of exp exp | Lindex of exp exp
/** A sizeof expression. [Sizeof typ (Some len)] represents the size of a value of type [typ] /** A sizeof expression. [Sizeof (Tarray elt (Some static_length)) (Some dynamic_length)]
which ends in an extensible array of length [len]. The length in [Tarray] records the represents the size of an array value consisting of [dynamic_length] elements of type [elt].
statically determined length, while the length in [Sizeof] records the dynamic length. */ The [dynamic_length], tracked by symbolic execution, may differ from the [static_length]
| Sizeof of typ dynamic_length Subtype.t; obtained from the type definition, e.g. when an array is over-allocated. For struct types,
the [dynamic_length] is that of the final extensible array, if any. */
| Sizeof of Typ.t dynamic_length Subtype.t;
/** the element typ of the final extensible array in the given typ, if any */
let get_extensible_array_element_typ: typ => option typ;
let struct_typ_equal: struct_typ => struct_typ => bool;
/** if [struct_typ] is a class, return its class kind (Java, CPP, or Obj-C) */
let struct_typ_get_class_kind: struct_typ => option Csu.class_kind;
/** return true if [struct_typ] is a Java class */
let struct_typ_is_java_class: struct_typ => bool;
/** return true if [struct_typ] is a C++ class. Note that this returns false for raw structs. */
let struct_typ_is_cpp_class: struct_typ => bool;
/** return true if [struct_typ] is an Obj-C class. Note that this returns false for raw structs. */
let struct_typ_is_objc_class: struct_typ => bool;
/** Sets of types. */
let module StructTypSet: Set.S with type elt = struct_typ;
let module TypSet: Set.S with type elt = typ;
/** Maps with type keys. */
let module TypMap: Map.S with type key = typ;
let module AnnotMap: PrettyPrintable.PPMap with type key = annotation;
/** Sets of expressions. */ /** Sets of expressions. */
@ -380,21 +267,21 @@ type stackop =
/** An instruction. */ /** An instruction. */
type instr = type instr =
/** declaration [let x = *lexp:typ] where [typ] is the root type of [lexp] */ /** declaration [let x = *lexp:typ] where [typ] is the root type of [lexp] */
| Letderef of Ident.t exp typ Location.t | Letderef of Ident.t exp Typ.t Location.t
/** assignment [*lexp1:typ = exp2] where [typ] is the root type of [lexp1] */ /** assignment [*lexp1:typ = exp2] where [typ] is the root type of [lexp1] */
| Set of exp typ exp Location.t | Set of exp Typ.t exp Location.t
/** prune the state based on [exp=1], the boolean indicates whether true branch */ /** prune the state based on [exp=1], the boolean indicates whether true branch */
| Prune of exp Location.t bool if_kind | Prune of exp Location.t bool if_kind
/** [Call (ret_id1..ret_idn, e_fun, arg_ts, loc, call_flags)] represents an instructions /** [Call (ret_id1..ret_idn, e_fun, arg_ts, loc, call_flags)] represents an instructions
[ret_id1..ret_idn = e_fun(arg_ts);] [ret_id1..ret_idn = e_fun(arg_ts);]
where n = 0 for void return and n > 1 for struct return */ where n = 0 for void return and n > 1 for struct return */
| Call of (list Ident.t) exp (list (exp, typ)) Location.t call_flags | Call of (list Ident.t) exp (list (exp, Typ.t)) Location.t call_flags
/** nullify stack variable */ /** nullify stack variable */
| Nullify of Pvar.t Location.t | Nullify of Pvar.t Location.t
| Abstract of Location.t /** apply abstraction */ | Abstract of Location.t /** apply abstraction */
| Remove_temps of (list Ident.t) Location.t /** remove temporaries */ | Remove_temps of (list Ident.t) Location.t /** remove temporaries */
| Stackop of stackop Location.t /** operation on the stack of propsets */ | Stackop of stackop Location.t /** operation on the stack of propsets */
| Declare_locals of (list (Pvar.t, typ)) Location.t /** declare local variables */; | Declare_locals of (list (Pvar.t, Typ.t)) Location.t /** declare local variables */;
/** Check if an instruction is auxiliary, or if it comes from source instructions. */ /** Check if an instruction is auxiliary, or if it comes from source instructions. */
@ -402,7 +289,7 @@ let instr_is_auxiliary: instr => bool;
/** Offset for an lvalue. */ /** Offset for an lvalue. */
type offset = | Off_fld of Ident.fieldname typ | Off_index of exp; type offset = | Off_fld of Ident.fieldname Typ.t | Off_index of exp;
/** {2 Components of Propositions} */ /** {2 Components of Propositions} */
@ -561,24 +448,8 @@ let hpred_compact: sharing_env => hpred => hpred;
/** {2 Comparision And Inspection Functions} */ /** {2 Comparision And Inspection Functions} */
let is_objc_ref_counter_field: (Ident.fieldname, typ, item_annotation) => bool;
let has_objc_ref_counter: hpred => bool; let has_objc_ref_counter: hpred => bool;
let objc_class_annotation: list (annotation, bool);
let cpp_class_annotation: list (annotation, bool);
let is_objc_class: typ => bool;
let is_cpp_class: typ => bool;
let is_java_class: typ => bool;
let is_array_of_cpp_class: typ => bool;
let is_pointer_to_cpp_class: typ => bool;
let exp_is_zero: exp => bool; let exp_is_zero: exp => bool;
let exp_is_null_literal: exp => bool; let exp_is_null_literal: exp => bool;
@ -589,11 +460,7 @@ let exp_is_this: exp => bool;
let path_pos_equal: path_pos => path_pos => bool; let path_pos_equal: path_pos => path_pos => bool;
let zero_value_of_numerical_type: Typ.t => exp;
/** turn a *T into a T. fails if [typ] is not a pointer type */
let typ_strip_ptr: typ => typ;
let zero_value_of_numerical_type: typ => exp;
/** Make a static local name in objc */ /** Make a static local name in objc */
@ -610,48 +477,6 @@ let block_pvar: Pvar.t;
/** Check if a pvar is a local pointing to a block in objc */ /** Check if a pvar is a local pointing to a block in objc */
let is_block_pvar: Pvar.t => bool; let is_block_pvar: Pvar.t => bool;
/** Check if type is a type for a block in objc */
let is_block_type: typ => bool;
/** Comparision for fieldnames. */
let fld_compare: Ident.fieldname => Ident.fieldname => int;
/** Equality for fieldnames. */
let fld_equal: Ident.fieldname => Ident.fieldname => bool;
/** Check wheter the integer kind is a char */
let ikind_is_char: ikind => bool;
/** Check wheter the integer kind is unsigned */
let ikind_is_unsigned: ikind => bool;
/** Convert an int64 into an IntLit.t given the kind:
the int64 is interpreted as unsigned according to the kind */
let int_of_int64_kind: int64 => ikind => IntLit.t;
/** Comparision for ptr_kind */
let ptr_kind_compare: ptr_kind => ptr_kind => int;
/** Comparision for types. */
let typ_compare: typ => typ => int;
/** Equality for types. */
let typ_equal: typ => typ => bool;
/** Comparision for fieldnames * types * item annotations. */
let fld_typ_ann_compare:
(Ident.fieldname, typ, item_annotation) => (Ident.fieldname, typ, item_annotation) => int;
let unop_equal: unop => unop => bool; let unop_equal: unop => unop => bool;
let binop_equal: binop => binop => bool; let binop_equal: binop => binop => bool;
@ -684,6 +509,19 @@ let attribute_compare: attribute => attribute => int;
let attribute_equal: attribute => attribute => bool; let attribute_equal: attribute => attribute => bool;
/** Categories of attributes */
type attribute_category =
| ACresource
| ACautorelease
| ACtaint
| AClock
| ACdiv0
| ACobjc_null
| ACundef
| ACretval
| ACobserver;
let attribute_category_compare: attribute_category => attribute_category => int; let attribute_category_compare: attribute_category => attribute_category => int;
let attribute_category_equal: attribute_category => attribute_category => bool; let attribute_category_equal: attribute_category => attribute_category => bool;
@ -712,7 +550,7 @@ let exp_is_array_index_of: exp => exp => bool;
let call_flags_compare: call_flags => call_flags => int; let call_flags_compare: call_flags => call_flags => int;
let exp_typ_compare: (exp, typ) => (exp, typ) => int; let exp_typ_compare: (exp, Typ.t) => (exp, Typ.t) => int;
let instr_compare: instr => instr => int; let instr_compare: instr => instr => int;
@ -762,38 +600,6 @@ let exp_strexp_compare: (exp, strexp) => (exp, strexp) => int;
let hpred_get_lhs: hpred => exp; let hpred_get_lhs: hpred => exp;
/** Field used for objective-c reference counting */
let objc_ref_counter_field: (Ident.fieldname, typ, item_annotation);
/** Compare function for annotations. */
let annotation_compare: annotation => annotation => int;
/** Compare function for annotation items. */
let item_annotation_compare: item_annotation => item_annotation => int;
/** Compare function for Method annotations. */
let method_annotation_compare: method_annotation => method_annotation => int;
/** Empty item annotation. */
let item_annotation_empty: item_annotation;
/** Empty method annotation. */
let method_annotation_empty: method_annotation;
/** Check if the item annodation is empty. */
let item_annotation_is_empty: item_annotation => bool;
/** Check if the method annodation is empty. */
let method_annotation_is_empty: method_annotation => bool;
/** Return the value of the FA_sentinel attribute in [attr_list] if it is found */ /** Return the value of the FA_sentinel attribute in [attr_list] if it is found */
let get_sentinel_func_attribute_value: list func_attribute => option (int, int); let get_sentinel_func_attribute_value: list func_attribute => option (int, int);
@ -823,56 +629,10 @@ let mem_alloc_pname: mem_kind => Procname.t;
let mem_dealloc_pname: mem_kind => Procname.t; let mem_dealloc_pname: mem_kind => Procname.t;
/** Pretty print an annotation. */
let pp_annotation: F.formatter => annotation => unit;
/** Pretty print a const. */ /** Pretty print a const. */
let pp_const: printenv => F.formatter => const => unit; let pp_const: printenv => F.formatter => const => unit;
/** Pretty print an item annotation. */
let pp_item_annotation: F.formatter => item_annotation => unit;
let item_annotation_to_string: item_annotation => string;
/** Pretty print a method annotation. */
let pp_method_annotation: string => F.formatter => method_annotation => unit;
/** Pretty print a type. */
let pp_typ: printenv => F.formatter => typ => unit;
let pp_struct_typ: printenv => (F.formatter => unit => unit) => F.formatter => struct_typ => unit;
/** Pretty print a type with all the details. */
let pp_typ_full: printenv => F.formatter => typ => unit;
let typ_to_string: typ => string;
/** [pp_type_decl pe pp_base pp_len f typ] pretty prints a type declaration.
pp_base prints the variable for a declaration, or can be skip to print only the type
pp_len prints the expression for the array length */
let pp_type_decl:
printenv =>
(F.formatter => unit => unit) =>
(printenv => F.formatter => exp => unit) =>
F.formatter =>
typ =>
unit;
/** Dump a type with all the details. */
let d_typ_full: typ => unit;
/** Dump a list of types. */
let d_typ_list: list typ => unit;
/** convert the attribute to a string */ /** convert the attribute to a string */
let attribute_to_string: printenv => attribute => string; let attribute_to_string: printenv => attribute => string;
@ -890,7 +650,7 @@ let pp_exp: printenv => F.formatter => exp => unit;
/** Pretty print an expression with type. */ /** Pretty print an expression with type. */
let pp_exp_typ: printenv => F.formatter => (exp, typ) => unit; let pp_exp_typ: printenv => F.formatter => (exp, Typ.t) => unit;
/** Convert an expression to a string */ /** Convert an expression to a string */
@ -1094,17 +854,7 @@ let hpred_list_get_lexps: (exp => bool) => list hpred => list exp;
/** {2 Utility Functions for Expressions} */ /** {2 Utility Functions for Expressions} */
/** Turn an expression representing a type into the type it represents /** Turn an expression representing a type into the type it represents
If not a sizeof, return the default type if given, otherwise raise an exception */ If not a sizeof, return the default type if given, otherwise raise an exception */
let texp_to_typ: option typ => exp => typ; let texp_to_typ: option Typ.t => exp => Typ.t;
/** If a struct type with field f, return the type of f.
If not, return the default type if given, otherwise raise an exception */
let struct_typ_fld: option typ => Ident.fieldname => typ => typ;
/** If an array type, return the type of the element.
If not, return the default type if given, otherwise raise an exception */
let array_typ_elem: option typ => typ => typ;
/** Return the root of [lexp]. */ /** Return the root of [lexp]. */

@ -23,7 +23,7 @@ let module TypenameHash = Hashtbl.Make {
/** Type for type environment. */ /** Type for type environment. */
type t = TypenameHash.t Sil.struct_typ; type t = TypenameHash.t Typ.struct_typ;
/** Create a new type environment. */ /** Create a new type environment. */
@ -46,19 +46,19 @@ let lookup_java_typ_from_string tenv typ_str => {
let rec loop = let rec loop =
fun fun
| "" | ""
| "void" => Some Sil.Tvoid | "void" => Some Typ.Tvoid
| "int" => Some (Sil.Tint Sil.IInt) | "int" => Some (Typ.Tint Typ.IInt)
| "byte" => Some (Sil.Tint Sil.IShort) | "byte" => Some (Typ.Tint Typ.IShort)
| "short" => Some (Sil.Tint Sil.IShort) | "short" => Some (Typ.Tint Typ.IShort)
| "boolean" => Some (Sil.Tint Sil.IBool) | "boolean" => Some (Typ.Tint Typ.IBool)
| "char" => Some (Sil.Tint Sil.IChar) | "char" => Some (Typ.Tint Typ.IChar)
| "long" => Some (Sil.Tint Sil.ILong) | "long" => Some (Typ.Tint Typ.ILong)
| "float" => Some (Sil.Tfloat Sil.FFloat) | "float" => Some (Typ.Tfloat Typ.FFloat)
| "double" => Some (Sil.Tfloat Sil.FDouble) | "double" => Some (Typ.Tfloat Typ.FDouble)
| typ_str when String.contains typ_str '[' => { | typ_str when String.contains typ_str '[' => {
let stripped_typ = String.sub typ_str 0 (String.length typ_str - 2); let stripped_typ = String.sub typ_str 0 (String.length typ_str - 2);
switch (loop stripped_typ) { switch (loop stripped_typ) {
| Some typ => Some (Sil.Tptr (Sil.Tarray typ None) Sil.Pk_pointer) | Some typ => Some (Typ.Tptr (Typ.Tarray typ None) Typ.Pk_pointer)
| None => None | None => None
} }
} }
@ -67,7 +67,7 @@ let lookup_java_typ_from_string tenv typ_str => {
{ {
let typename = Typename.Java.from_string typ_str; let typename = Typename.Java.from_string typ_str;
switch (lookup tenv typename) { switch (lookup tenv typename) {
| Some struct_typ => Some (Sil.Tstruct struct_typ) | Some struct_typ => Some (Typ.Tstruct struct_typ)
| None => None | None => None
} }
}; };
@ -79,7 +79,7 @@ let lookup_java_typ_from_string tenv typ_str => {
typs, use [lookup_java_typ_from_string] */ typs, use [lookup_java_typ_from_string] */
let lookup_java_class_from_string tenv typ_str => let lookup_java_class_from_string tenv typ_str =>
switch (lookup_java_typ_from_string tenv typ_str) { switch (lookup_java_typ_from_string tenv typ_str) {
| Some (Sil.Tstruct struct_typ) => Some struct_typ | Some (Typ.Tstruct struct_typ) => Some struct_typ
| _ => None | _ => None
}; };
@ -102,7 +102,7 @@ let proc_extract_return_typ tenv pname_java =>
let get_overriden_method tenv pname_java => { let get_overriden_method tenv pname_java => {
let struct_typ_get_def_method_by_name struct_typ method_name => let struct_typ_get_def_method_by_name struct_typ method_name =>
IList.find IList.find
(fun def_method => method_name == Procname.get_method def_method) struct_typ.Sil.def_methods; (fun def_method => method_name == Procname.get_method def_method) struct_typ.Typ.def_methods;
let rec get_overriden_method_in_superclasses pname_java superclasses => let rec get_overriden_method_in_superclasses pname_java superclasses =>
switch superclasses { switch superclasses {
| [superclass, ...superclasses_tail] => | [superclass, ...superclasses_tail] =>
@ -113,7 +113,7 @@ let get_overriden_method tenv pname_java => {
) { ) {
| Not_found => | Not_found =>
get_overriden_method_in_superclasses get_overriden_method_in_superclasses
pname_java (superclasses_tail @ struct_typ.Sil.superclasses) pname_java (superclasses_tail @ struct_typ.Typ.superclasses)
} }
| None => get_overriden_method_in_superclasses pname_java superclasses_tail | None => get_overriden_method_in_superclasses pname_java superclasses_tail
} }
@ -130,10 +130,10 @@ let get_overriden_method tenv pname_java => {
/** expand a type if it is a typename by looking it up in the type environment */ /** expand a type if it is a typename by looking it up in the type environment */
let expand_type tenv typ => let expand_type tenv typ =>
switch typ { switch typ {
| Sil.Tvar tname => | Typ.Tvar tname =>
switch (lookup tenv tname) { switch (lookup tenv tname) {
| None => assert false | None => assert false
| Some struct_typ => Sil.Tstruct struct_typ | Some struct_typ => Typ.Tstruct struct_typ
} }
| _ => typ | _ => typ
}; };
@ -168,7 +168,7 @@ let pp fmt (tenv: t) =>
( (
fun name typ => { fun name typ => {
Format.fprintf fmt "@[<6>NAME: %s@." (Typename.to_string name); Format.fprintf fmt "@[<6>NAME: %s@." (Typename.to_string name);
Format.fprintf fmt "@[<6>TYPE: %a@." (Sil.pp_struct_typ pe_text (fun _ () => ())) typ Format.fprintf fmt "@[<6>TYPE: %a@." (Typ.pp_struct_typ pe_text (fun _ () => ())) typ
} }
) )
tenv; tenv;

@ -18,7 +18,7 @@ type t; /** Type for type environment. */
/** Add a (name,typename) pair to the global type environment. */ /** Add a (name,typename) pair to the global type environment. */
let add: t => Typename.t => Sil.struct_typ => unit; let add: t => Typename.t => Typ.struct_typ => unit;
/** Create a new type environment. */ /** Create a new type environment. */
@ -26,15 +26,15 @@ let create: unit => t;
/** Expand a type if it is a typename by looking it up in the type environment. */ /** Expand a type if it is a typename by looking it up in the type environment. */
let expand_type: t => Sil.typ => Sil.typ; let expand_type: t => Typ.t => Typ.t;
/** Fold a function over the elements of the type environment. */ /** Fold a function over the elements of the type environment. */
let fold: (Typename.t => Sil.struct_typ => 'a => 'a) => t => 'a => 'a; let fold: (Typename.t => Typ.struct_typ => 'a => 'a) => t => 'a => 'a;
/** iterate over a type environment */ /** iterate over a type environment */
let iter: (Typename.t => Sil.struct_typ => unit) => t => unit; let iter: (Typename.t => Typ.struct_typ => unit) => t => unit;
/** Load a type environment from a file */ /** Load a type environment from a file */
@ -42,24 +42,24 @@ let load_from_file: DB.filename => option t;
/** Look up a name in the global type environment. */ /** Look up a name in the global type environment. */
let lookup: t => Typename.t => option Sil.struct_typ; let lookup: t => Typename.t => option Typ.struct_typ;
/** Lookup Java types by name. */ /** Lookup Java types by name. */
let lookup_java_typ_from_string: t => string => option Sil.typ; let lookup_java_typ_from_string: t => string => option Typ.t;
/** resolve a type string to a Java *class* type. For strings that may represent primitive or array /** resolve a type string to a Java *class* type. For strings that may represent primitive or array
typs, use [lookup_java_typ_from_string]. */ typs, use [lookup_java_typ_from_string]. */
let lookup_java_class_from_string: t => string => option Sil.struct_typ; let lookup_java_class_from_string: t => string => option Typ.struct_typ;
/** Return the declaring class type of [pname_java] */ /** Return the declaring class type of [pname_java] */
let proc_extract_declaring_class_typ: t => Procname.java => option Sil.struct_typ; let proc_extract_declaring_class_typ: t => Procname.java => option Typ.struct_typ;
/** Return the return type of [pname_java]. */ /** Return the return type of [pname_java]. */
let proc_extract_return_typ: t => Procname.java => option Sil.typ; let proc_extract_return_typ: t => Procname.java => option Typ.t;
/** Check if typename is found in t */ /** Check if typename is found in t */

@ -0,0 +1,602 @@
/*
* 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: Types */
let module L = Logging;
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 */
type ikind =
| IChar /** [char] */
| ISChar /** [signed char] */
| IUChar /** [unsigned char] */
| IBool /** [bool] */
| IInt /** [int] */
| IUInt /** [unsigned int] */
| IShort /** [short] */
| IUShort /** [unsigned short] */
| ILong /** [long] */
| IULong /** [unsigned long] */
| ILongLong /** [long long] (or [_int64] on Microsoft Visual C) */
| IULongLong /** [unsigned long long] (or [unsigned _int64] on Microsoft Visual C) */
| I128 /** [__int128_t] */
| IU128 /** [__uint128_t] */;
/** comparison for ikind */
let ikind_compare k1 k2 =>
switch (k1, k2) {
| (IChar, IChar) => 0
| (IChar, _) => (-1)
| (_, IChar) => 1
| (ISChar, ISChar) => 0
| (ISChar, _) => (-1)
| (_, ISChar) => 1
| (IUChar, IUChar) => 0
| (IUChar, _) => (-1)
| (_, IUChar) => 1
| (IBool, IBool) => 0
| (IBool, _) => (-1)
| (_, IBool) => 1
| (IInt, IInt) => 0
| (IInt, _) => (-1)
| (_, IInt) => 1
| (IUInt, IUInt) => 0
| (IUInt, _) => (-1)
| (_, IUInt) => 1
| (IShort, IShort) => 0
| (IShort, _) => (-1)
| (_, IShort) => 1
| (IUShort, IUShort) => 0
| (IUShort, _) => (-1)
| (_, IUShort) => 1
| (ILong, ILong) => 0
| (ILong, _) => (-1)
| (_, ILong) => 1
| (IULong, IULong) => 0
| (IULong, _) => (-1)
| (_, IULong) => 1
| (ILongLong, ILongLong) => 0
| (ILongLong, _) => (-1)
| (_, ILongLong) => 1
| (IULongLong, IULongLong) => 0
| (IULongLong, _) => (-1)
| (_, IULongLong) => 1
| (I128, I128) => 0
| (I128, _) => (-1)
| (_, I128) => 1
| (IU128, IU128) => 0
};
let ikind_to_string =
fun
| IChar => "char"
| ISChar => "signed char"
| IUChar => "unsigned char"
| IBool => "_Bool"
| IInt => "int"
| IUInt => "unsigned int"
| IShort => "short"
| IUShort => "unsigned short"
| ILong => "long"
| IULong => "unsigned long"
| ILongLong => "long long"
| IULongLong => "unsigned long long"
| I128 => "__int128_t"
| IU128 => "__uint128_t";
let ikind_is_char =
fun
| IChar
| ISChar
| IUChar => true
| _ => false;
let ikind_is_unsigned =
fun
| IUChar
| IUInt
| IUShort
| IULong
| IULongLong => true
| _ => false;
let int_of_int64_kind i ik => IntLit.of_int64_unsigned i (ikind_is_unsigned ik);
/** Kinds of floating-point numbers */
type fkind =
| FFloat /** [float] */
| FDouble /** [double] */
| FLongDouble /** [long double] */;
/** comparison for fkind */
let fkind_compare k1 k2 =>
switch (k1, k2) {
| (FFloat, FFloat) => 0
| (FFloat, _) => (-1)
| (_, FFloat) => 1
| (FDouble, FDouble) => 0
| (FDouble, _) => (-1)
| (_, FDouble) => 1
| (FLongDouble, FLongDouble) => 0
};
let fkind_to_string =
fun
| FFloat => "float"
| FDouble => "double"
| FLongDouble => "long double";
/** kind of pointer */
type ptr_kind =
| Pk_pointer /** C/C++, Java, Objc standard/__strong pointer */
| Pk_reference /** C++ reference */
| Pk_objc_weak /** Obj-C __weak pointer */
| Pk_objc_unsafe_unretained /** Obj-C __unsafe_unretained pointer */
| Pk_objc_autoreleasing /** Obj-C __autoreleasing pointer */;
let ptr_kind_compare pk1 pk2 =>
switch (pk1, pk2) {
| (Pk_pointer, Pk_pointer) => 0
| (Pk_pointer, _) => (-1)
| (_, Pk_pointer) => 1
| (Pk_reference, Pk_reference) => 0
| (_, Pk_reference) => (-1)
| (Pk_reference, _) => 1
| (Pk_objc_weak, Pk_objc_weak) => 0
| (Pk_objc_weak, _) => (-1)
| (_, Pk_objc_weak) => 1
| (Pk_objc_unsafe_unretained, Pk_objc_unsafe_unretained) => 0
| (Pk_objc_unsafe_unretained, _) => (-1)
| (_, Pk_objc_unsafe_unretained) => 1
| (Pk_objc_autoreleasing, Pk_objc_autoreleasing) => 0
};
let ptr_kind_string =
fun
| Pk_reference => "&"
| Pk_pointer => "*"
| Pk_objc_weak => "__weak *"
| Pk_objc_unsafe_unretained => "__unsafe_unretained *"
| Pk_objc_autoreleasing => "__autoreleasing *";
/** statically determined length of an array type, if any */
type static_length = option IntLit.t;
type struct_fields = list (Ident.fieldname, t, item_annotation)
/** Type for a structured value. */
and struct_typ = {
instance_fields: struct_fields, /** non-static fields */
static_fields: struct_fields, /** static fields */
csu: Csu.t, /** class/struct/union */
struct_name: option Mangled.t, /** name */
superclasses: list Typename.t, /** list of superclasses */
def_methods: list Procname.t, /** methods defined */
struct_annotations: item_annotation /** annotations */
}
/** types for sil (structured) expressions */
and t =
| Tvar of Typename.t /** named type */
| Tint of ikind /** integer type */
| Tfloat of fkind /** float type */
| Tvoid /** void type */
| Tfun of bool /** function type with noreturn attribute */
| Tptr of t ptr_kind /** pointer type */
| Tstruct of struct_typ /** Type for a structured value */
| Tarray of t static_length /** array type with statically fixed length */;
let cname_opt_compare nameo1 nameo2 =>
switch (nameo1, nameo2) {
| (None, None) => 0
| (None, _) => (-1)
| (_, None) => 1
| (Some n1, Some n2) => Mangled.compare n1 n2
};
let rec fld_typ_ann_compare fta1 fta2 =>
triple_compare Ident.fieldname_compare compare item_annotation_compare fta1 fta2
and fld_typ_ann_list_compare ftal1 ftal2 => IList.compare fld_typ_ann_compare ftal1 ftal2
and struct_typ_compare struct_typ1 struct_typ2 =>
if (struct_typ1.csu == Csu.Class Csu.Java && struct_typ2.csu == Csu.Class Csu.Java) {
cname_opt_compare struct_typ1.struct_name struct_typ2.struct_name
} else {
let n = fld_typ_ann_list_compare struct_typ1.instance_fields struct_typ2.instance_fields;
if (n != 0) {
n
} else {
let n = fld_typ_ann_list_compare struct_typ1.static_fields struct_typ2.static_fields;
if (n != 0) {
n
} else {
let n = Csu.compare struct_typ1.csu struct_typ2.csu;
if (n != 0) {
n
} else {
cname_opt_compare struct_typ1.struct_name struct_typ2.struct_name
}
}
}
}
/** Comparision for types. */
and compare t1 t2 =>
if (t1 === t2) {
0
} else {
switch (t1, t2) {
| (Tvar tn1, Tvar tn2) => Typename.compare tn1 tn2
| (Tvar _, _) => (-1)
| (_, Tvar _) => 1
| (Tint ik1, Tint ik2) => ikind_compare ik1 ik2
| (Tint _, _) => (-1)
| (_, Tint _) => 1
| (Tfloat fk1, Tfloat fk2) => fkind_compare fk1 fk2
| (Tfloat _, _) => (-1)
| (_, Tfloat _) => 1
| (Tvoid, Tvoid) => 0
| (Tvoid, _) => (-1)
| (_, Tvoid) => 1
| (Tfun noreturn1, Tfun noreturn2) => bool_compare noreturn1 noreturn2
| (Tfun _, _) => (-1)
| (_, Tfun _) => 1
| (Tptr t1' pk1, Tptr t2' pk2) =>
let n = compare t1' t2';
if (n != 0) {
n
} else {
ptr_kind_compare pk1 pk2
}
| (Tptr _, _) => (-1)
| (_, Tptr _) => 1
| (Tstruct struct_typ1, Tstruct struct_typ2) => struct_typ_compare struct_typ1 struct_typ2
| (Tstruct _, _) => (-1)
| (_, Tstruct _) => 1
| (Tarray t1 _, Tarray t2 _) => compare t1 t2
}
};
let struct_typ_equal struct_typ1 struct_typ2 => struct_typ_compare struct_typ1 struct_typ2 == 0;
let equal t1 t2 => compare t1 t2 == 0;
let rec pp_struct_typ pe pp_base f struct_typ =>
switch struct_typ.struct_name {
| Some name when false =>
/* remove "when false" to print the details of struct */
F.fprintf
f
"%s %a {%a} %a"
(Csu.name struct_typ.csu)
Mangled.pp
name
(pp_seq (fun f (fld, t, _) => F.fprintf f "%a %a" (pp_full pe) t Ident.pp_fieldname fld))
struct_typ.instance_fields
pp_base
()
| Some name => F.fprintf f "%s %a %a" (Csu.name struct_typ.csu) Mangled.pp name pp_base ()
| None =>
F.fprintf
f
"%s {%a} %a"
(Csu.name struct_typ.csu)
(pp_seq (fun f (fld, t, _) => F.fprintf f "%a %a" (pp_full pe) t Ident.pp_fieldname fld))
struct_typ.instance_fields
pp_base
()
}
/** Pretty print a type declaration.
pp_base prints the variable for a declaration, or can be skip to print only the type */
and pp_decl pe pp_base f =>
fun
| Tvar tname => F.fprintf f "%s %a" (Typename.to_string tname) pp_base ()
| Tint ik => F.fprintf f "%s %a" (ikind_to_string ik) pp_base ()
| Tfloat fk => F.fprintf f "%s %a" (fkind_to_string fk) pp_base ()
| Tvoid => F.fprintf f "void %a" pp_base ()
| Tfun false => F.fprintf f "_fn_ %a" pp_base ()
| Tfun true => F.fprintf f "_fn_noreturn_ %a" pp_base ()
| Tptr ((Tarray _ | Tfun _) as typ) pk => {
let pp_base' fmt () => F.fprintf fmt "(%s%a)" (ptr_kind_string pk) pp_base ();
pp_decl pe pp_base' f typ
}
| Tptr typ pk => {
let pp_base' fmt () => F.fprintf fmt "%s%a" (ptr_kind_string pk) pp_base ();
pp_decl pe pp_base' f typ
}
| Tstruct struct_typ => pp_struct_typ pe pp_base f struct_typ
| Tarray typ static_len => {
let pp_array_static_len fmt => (
fun
| Some static_len => IntLit.pp fmt static_len
| None => F.fprintf fmt "_"
);
let pp_base' fmt () => F.fprintf fmt "%a[%a]" pp_base () pp_array_static_len static_len;
pp_decl pe pp_base' f typ
}
/** Pretty print a type with all the details, using the C syntax. */
and pp_full pe => pp_decl pe (fun _ () => ())
/** Pretty print a type. Do nothing by default. */
and pp pe f te =>
if Config.print_types {
pp_full pe f te
} else {
()
};
let to_string typ => {
let pp fmt () => pp_full pe_text fmt typ;
pp_to_string pp ()
};
/** dump a type with all the details. */
let d_full (t: t) => L.add_print_action (L.PTtyp_full, Obj.repr t);
/** dump a list of types. */
let d_list (tl: list t) => L.add_print_action (L.PTtyp_list, Obj.repr tl);
/** {2 Sets and maps of types} */
let module StructSet = Set.Make {
type t = struct_typ;
let compare = struct_typ_compare;
};
let module Set = Set.Make {
type nonrec t = t;
let compare = compare;
};
let module Map = Map.Make {
type nonrec t = t;
let compare = compare;
};
let module Tbl = Hashtbl.Make {
type nonrec t = t;
let equal = equal;
let hash = Hashtbl.hash;
};
let unsome s =>
fun
| Some default_typ => default_typ
| None => {
L.err "No default typ in %s@." s;
assert false
};
/** turn a *T into a T. fails if [typ] is not a pointer type */
let strip_ptr =
fun
| Tptr t _ => t
| _ => assert false;
/** If an array type, return the type of the element.
If not, return the default type if given, otherwise raise an exception */
let array_elem default_opt =>
fun
| Tarray t_el _ => t_el
| _ => unsome "array_elem" default_opt;
/** the element typ of the final extensible array in the given typ, if any */
let rec get_extensible_array_element_typ =
fun
| Tarray typ _ => Some typ
| Tstruct {instance_fields} =>
Option.map_default
(fun (_, fld_typ, _) => get_extensible_array_element_typ fld_typ)
None
(IList.last instance_fields)
| _ => None;
/** If a struct type with field f, return the type of f.
If not, return the default type if given, otherwise raise an exception */
let struct_typ_fld default_opt f => {
let def () => unsome "struct_typ_fld" default_opt;
fun
| Tstruct struct_typ =>
try (
(fun (_, y, _) => y) (
IList.find (fun (_f, _, _) => Ident.fieldname_equal _f f) struct_typ.instance_fields
)
) {
| Not_found => def ()
}
| _ => def ()
};
/** if [struct_typ] is a class, return its class kind (Java, CPP, or Obj-C) */
let struct_typ_get_class_kind struct_typ =>
switch struct_typ.csu {
| Csu.Class class_kind => Some class_kind
| _ => None
};
/** return true if [struct_typ] is a Java class */
let struct_typ_is_java_class struct_typ =>
switch (struct_typ_get_class_kind struct_typ) {
| Some Csu.Java => true
| _ => false
};
/** return true if [struct_typ] is a C++ class. Note that this returns false for raw structs. */
let struct_typ_is_cpp_class struct_typ =>
switch (struct_typ_get_class_kind struct_typ) {
| Some Csu.CPP => true
| _ => false
};
/** return true if [struct_typ] is an Obj-C class. Note that this returns false for raw structs. */
let struct_typ_is_objc_class struct_typ =>
switch (struct_typ_get_class_kind struct_typ) {
| Some Csu.Objc => true
| _ => false
};
let is_class_of_kind typ ck =>
switch typ {
| Tstruct {csu: Csu.Class ck'} => ck == ck'
| _ => false
};
let is_objc_class typ => is_class_of_kind typ Csu.Objc;
let is_cpp_class typ => is_class_of_kind typ Csu.CPP;
let is_java_class typ => is_class_of_kind typ Csu.Java;
let rec is_array_of_cpp_class typ =>
switch typ {
| Tarray typ _ => is_array_of_cpp_class typ
| _ => is_cpp_class typ
};
let is_pointer_to_cpp_class typ =>
switch typ {
| Tptr t _ => is_cpp_class t
| _ => false
};
let has_block_prefix s =>
switch (Str.split_delim (Str.regexp_string Config.anonymous_block_prefix) s) {
| [_, _, ..._] => true
| _ => false
};
/** Check if type is a type for a block in objc */
let is_block_type typ => has_block_prefix (to_string typ);
let objc_ref_counter_annot = [({class_name: "ref_counter", parameters: []}, false)];
/** Field used for objective-c reference counting */
let objc_ref_counter_field = (Ident.fieldname_hidden, Tint IInt, objc_ref_counter_annot);
let is_objc_ref_counter_field (fld, _, a) =>
Ident.fieldname_is_hidden fld && item_annotation_compare a objc_ref_counter_annot == 0;

@ -0,0 +1,268 @@
/*
* 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: Types */
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 */
type ikind =
| IChar /** [char] */
| ISChar /** [signed char] */
| IUChar /** [unsigned char] */
| IBool /** [bool] */
| IInt /** [int] */
| IUInt /** [unsigned int] */
| IShort /** [short] */
| IUShort /** [unsigned short] */
| ILong /** [long] */
| IULong /** [unsigned long] */
| ILongLong /** [long long] (or [_int64] on Microsoft Visual C) */
| IULongLong /** [unsigned long long] (or [unsigned _int64] on Microsoft Visual C) */
| I128 /** [__int128_t] */
| IU128 /** [__uint128_t] */;
/** Check wheter the integer kind is a char */
let ikind_is_char: ikind => bool;
/** Check wheter the integer kind is unsigned */
let ikind_is_unsigned: ikind => bool;
/** Convert an int64 into an IntLit.t given the kind:
the int64 is interpreted as unsigned according to the kind */
let int_of_int64_kind: int64 => ikind => IntLit.t;
/** Kinds of floating-point numbers */
type fkind =
| FFloat /** [float] */
| FDouble /** [double] */
| FLongDouble /** [long double] */;
/** kind of pointer */
type ptr_kind =
| Pk_pointer /** C/C++, Java, Objc standard/__strong pointer */
| Pk_reference /** C++ reference */
| Pk_objc_weak /** Obj-C __weak pointer */
| Pk_objc_unsafe_unretained /** Obj-C __unsafe_unretained pointer */
| Pk_objc_autoreleasing /** Obj-C __autoreleasing pointer */;
/** Comparision for ptr_kind */
let ptr_kind_compare: ptr_kind => ptr_kind => int;
/** statically determined length of an array type, if any */
type static_length = option IntLit.t;
type struct_fields = list (Ident.fieldname, t, item_annotation)
/** Type for a structured value. */
and struct_typ = {
instance_fields: struct_fields, /** non-static fields */
static_fields: struct_fields, /** static fields */
csu: Csu.t, /** class/struct/union */
struct_name: option Mangled.t, /** name */
superclasses: list Typename.t, /** list of superclasses */
def_methods: list Procname.t, /** methods defined */
struct_annotations: item_annotation /** annotations */
}
/** types for sil (structured) expressions */
and t =
| Tvar of Typename.t /** named type */
| Tint of ikind /** integer type */
| Tfloat of fkind /** float type */
| Tvoid /** void type */
| Tfun of bool /** function type with noreturn attribute */
| Tptr of t ptr_kind /** pointer type */
| Tstruct of struct_typ /** Type for a structured value */
| Tarray of t static_length /** array type with statically fixed length */;
/** Comparision for fieldnames * types * item annotations. */
let fld_typ_ann_compare:
(Ident.fieldname, t, item_annotation) => (Ident.fieldname, t, item_annotation) => int;
let struct_typ_equal: struct_typ => struct_typ => bool;
/** Comparision for types. */
let compare: t => t => int;
/** Equality for types. */
let equal: t => t => bool;
let pp_struct_typ: printenv => (F.formatter => unit => unit) => F.formatter => struct_typ => unit;
/** [pp_decl pe pp_base f typ] pretty prints a type declaration.
pp_base prints the variable for a declaration, or can be skip to print only the type */
let pp_decl: printenv => (F.formatter => unit => unit) => F.formatter => t => unit;
/** Pretty print a type with all the details. */
let pp_full: printenv => F.formatter => t => unit;
/** Pretty print a type. */
let pp: printenv => F.formatter => t => unit;
let to_string: t => string;
/** Dump a type with all the details. */
let d_full: t => unit;
/** Dump a list of types. */
let d_list: list t => unit;
/** Sets of types. */
let module StructSet: Set.S with type elt = struct_typ;
let module Set: Set.S with type elt = t;
/** Maps with type keys. */
let module Map: Map.S with type key = t;
let module Tbl: Hashtbl.S with type key = t;
/** turn a *T into a T. fails if [t] is not a pointer type */
let strip_ptr: t => t;
/** If an array type, return the type of the element.
If not, return the default type if given, otherwise raise an exception */
let array_elem: option t => t => t;
/** the element typ of the final extensible array in the given typ, if any */
let get_extensible_array_element_typ: t => option t;
/** If a struct type with field f, return the type of f.
If not, return the default type if given, otherwise raise an exception */
let struct_typ_fld: option t => Ident.fieldname => t => t;
/** if [struct_typ] is a class, return its class kind (Java, CPP, or Obj-C) */
let struct_typ_get_class_kind: struct_typ => option Csu.class_kind;
/** return true if [struct_typ] is a Java class */
let struct_typ_is_java_class: struct_typ => bool;
/** return true if [struct_typ] is a C++ class. Note that this returns false for raw structs. */
let struct_typ_is_cpp_class: struct_typ => bool;
/** return true if [struct_typ] is an Obj-C class. Note that this returns false for raw structs. */
let struct_typ_is_objc_class: struct_typ => bool;
let is_objc_class: t => bool;
let is_cpp_class: t => bool;
let is_java_class: t => bool;
let is_array_of_cpp_class: t => bool;
let is_pointer_to_cpp_class: t => bool;
let has_block_prefix: string => bool;
/** Check if type is a type for a block in objc */
let is_block_type: t => bool;
/** Field used for objective-c reference counting */
let objc_ref_counter_field: (Ident.fieldname, t, item_annotation);
let is_objc_ref_counter_field: (Ident.fieldname, t, item_annotation) => bool;
let unsome: string => option t => t;

@ -408,25 +408,25 @@ let mk_rules_for_dll (para : Sil.hpara_dll) : rule list =
let typ_get_recursive_flds tenv typ_exp = let typ_get_recursive_flds tenv typ_exp =
let filter typ (_, t, _) = let filter typ (_, t, _) =
match t with match t with
| Sil.Tvar _ | Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ -> false | Typ.Tvar _ | Typ.Tint _ | Typ.Tfloat _ | Typ.Tvoid | Typ.Tfun _ -> false
| Sil.Tptr (Sil.Tvar tname', _) -> | Typ.Tptr (Typ.Tvar tname', _) ->
let typ' = match Tenv.lookup tenv tname' with let typ' = match Tenv.lookup tenv tname' with
| None -> | None ->
L.err "@.typ_get_recursive: Undefined type %s@." (Typename.to_string tname'); L.err "@.typ_get_recursive: Undefined type %s@." (Typename.to_string tname');
t t
| Some st -> Sil.Tstruct st in | Some st -> Typ.Tstruct st in
Sil.typ_equal typ' typ Typ.equal typ' typ
| Sil.Tptr _ | Sil.Tstruct _ | Sil.Tarray _ -> | Typ.Tptr _ | Typ.Tstruct _ | Typ.Tarray _ ->
false false
in in
match typ_exp with match typ_exp with
| Sil.Sizeof (typ, _, _) -> | Sil.Sizeof (typ, _, _) ->
(match Tenv.expand_type tenv typ with (match Tenv.expand_type tenv typ with
| Sil.Tint _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _ | Sil.Tfloat _ -> [] | Typ.Tint _ | Typ.Tvoid | Typ.Tfun _ | Typ.Tptr _ | Typ.Tfloat _ -> []
| Sil.Tstruct { Sil.instance_fields } -> | Typ.Tstruct { Typ.instance_fields } ->
IList.map (fun (x, _, _) -> x) (IList.filter (filter typ) instance_fields) IList.map (fun (x, _, _) -> x) (IList.filter (filter typ) instance_fields)
| Sil.Tarray _ -> [] | Typ.Tarray _ -> []
| Sil.Tvar _ -> assert false) | Typ.Tvar _ -> assert false)
| Sil.Var _ -> [] (* type of |-> not known yet *) | Sil.Var _ -> [] (* type of |-> not known yet *)
| Sil.Const _ -> [] | Sil.Const _ -> []
| _ -> | _ ->
@ -469,7 +469,7 @@ let discover_para_candidates tenv p =
let edges = ref [] in let edges = ref [] in
let add_edge edg = edges := edg :: !edges in let add_edge edg = edges := edg :: !edges in
let get_edges_strexp rec_flds root se = let get_edges_strexp rec_flds root se =
let is_rec_fld fld = IList.exists (Sil.fld_equal fld) rec_flds in let is_rec_fld fld = IList.exists (Ident.fieldname_equal fld) rec_flds in
match se with match se with
| Sil.Eexp _ | Sil.Earray _ -> () | Sil.Eexp _ | Sil.Earray _ -> ()
| Sil.Estruct (fsel, _) -> | Sil.Estruct (fsel, _) ->
@ -505,7 +505,7 @@ let discover_para_dll_candidates tenv p =
let edges = ref [] in let edges = ref [] in
let add_edge edg = (edges := edg :: !edges) in let add_edge edg = (edges := edg :: !edges) in
let get_edges_strexp rec_flds root se = let get_edges_strexp rec_flds root se =
let is_rec_fld fld = IList.exists (Sil.fld_equal fld) rec_flds in let is_rec_fld fld = IList.exists (Ident.fieldname_equal fld) rec_flds in
match se with match se with
| Sil.Eexp _ | Sil.Earray _ -> () | Sil.Eexp _ | Sil.Earray _ -> ()
| Sil.Estruct (fsel, _) -> | Sil.Estruct (fsel, _) ->
@ -885,7 +885,8 @@ let get_cycle root prop =
IList.iter (fun ((e, t), f, e') -> IList.iter (fun ((e, t), f, e') ->
match e, e' with match e, e' with
| Sil.Eexp (e, _), Sil.Eexp (e', _) -> | Sil.Eexp (e, _), Sil.Eexp (e', _) ->
L.d_str ("("^(Sil.exp_to_string e)^": "^(Sil.typ_to_string t)^", "^(Ident.fieldname_to_string f)^", "^(Sil.exp_to_string e')^")") L.d_str ("("^(Sil.exp_to_string e)^": "^(Typ.to_string t)^", "
^(Ident.fieldname_to_string f)^", "^(Sil.exp_to_string e')^")")
| _ -> ()) cyc; | _ -> ()) cyc;
L.d_strln "") in L.d_strln "") in
(* perform a dfs of a graph stopping when e_root is reached. *) (* perform a dfs of a graph stopping when e_root is reached. *)
@ -950,7 +951,7 @@ let get_var_retain_cycle _prop =
let is_hpred_block v h = let is_hpred_block v h =
match h, v with match h, v with
| Sil.Hpointsto (e, _, Sil.Sizeof (typ, _, _)), Sil.Eexp (e', _) | Sil.Hpointsto (e, _, Sil.Sizeof (typ, _, _)), Sil.Eexp (e', _)
when Sil.exp_equal e e' && Sil.is_block_type typ -> true when Sil.exp_equal e e' && Typ.is_block_type typ -> true
| _, _ -> false in | _, _ -> false in
let find v = let find v =
try try
@ -994,7 +995,7 @@ let cycle_has_weak_or_unretained_or_assign_field cycle =
(* returns items annotation for field fn in struct t *) (* returns items annotation for field fn in struct t *)
let get_item_annotation t fn = let get_item_annotation t fn =
match t with match t with
| Sil.Tstruct { Sil.instance_fields; static_fields } -> | Typ.Tstruct { Typ.instance_fields; static_fields } ->
let ia = ref [] in let ia = ref [] in
IList.iter (fun (fn', _, ia') -> IList.iter (fun (fn', _, ia') ->
if Ident.fieldname_equal fn fn' then ia := ia') if Ident.fieldname_equal fn fn' then ia := ia')
@ -1007,8 +1008,9 @@ let cycle_has_weak_or_unretained_or_assign_field cycle =
| 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, _) =
((a.Sil.class_name = Config.property_attributes) || ((a.Typ.class_name = Config.property_attributes) ||
(a.Sil.class_name = Config.ivar_attributes)) && has_weak_or_unretained_or_assign a.Sil.parameters in (a.Typ.class_name = Config.ivar_attributes))
&& has_weak_or_unretained_or_assign a.Typ.parameters in
let rec do_cycle c = let rec do_cycle c =
match c with match c with
| [] -> false | [] -> false

@ -29,7 +29,7 @@ module StrexpMatch : sig
val path_from_exp_offsets : Sil.exp -> Sil.offset list -> path val path_from_exp_offsets : Sil.exp -> Sil.offset list -> path
(** path to the root, length, elements and type of a new_array *) (** path to the root, length, elements and type of a new_array *)
type strexp_data = path * Sil.strexp * Sil.typ type strexp_data = path * Sil.strexp * Typ.t
(** sigma with info about a current array *) (** sigma with info about a current array *)
type t type t
@ -58,7 +58,7 @@ module StrexpMatch : sig
end = struct end = struct
(** syntactic offset *) (** syntactic offset *)
type syn_offset = Field of Ident.fieldname * Sil.typ | Index of Sil.exp type syn_offset = Field of Ident.fieldname * Typ.t | Index of Sil.exp
(** path through an Estruct *) (** path through an Estruct *)
type path = Sil.exp * (syn_offset list) type path = Sil.exp * (syn_offset list)
@ -67,19 +67,19 @@ end = struct
let rec get_strexp_at_syn_offsets se t syn_offs = let rec get_strexp_at_syn_offsets se t syn_offs =
match se, t, syn_offs with match se, t, syn_offs with
| _, _, [] -> (se, t) | _, _, [] -> (se, t)
| Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields }, Field (fld, _) :: syn_offs' -> | Sil.Estruct (fsel, _), Typ.Tstruct { Typ.instance_fields }, Field (fld, _) :: syn_offs' ->
let se' = snd (IList.find (fun (f', _) -> Sil.fld_equal f' fld) fsel) in let se' = snd (IList.find (fun (f', _) -> Ident.fieldname_equal f' fld) fsel) in
let t' = (fun (_,y,_) -> y) let t' = (fun (_,y,_) -> y)
(IList.find (fun (f', _, _) -> (IList.find (fun (f', _, _) ->
Sil.fld_equal f' fld) instance_fields) in Ident.fieldname_equal f' fld) instance_fields) in
get_strexp_at_syn_offsets se' t' syn_offs' get_strexp_at_syn_offsets se' t' syn_offs'
| Sil.Earray (_, esel, _), Sil.Tarray (t', _), Index ind :: syn_offs' -> | Sil.Earray (_, esel, _), Typ.Tarray (t', _), Index ind :: syn_offs' ->
let se' = snd (IList.find (fun (i', _) -> Sil.exp_equal i' ind) esel) in let se' = snd (IList.find (fun (i', _) -> Sil.exp_equal i' ind) esel) in
get_strexp_at_syn_offsets se' t' syn_offs' get_strexp_at_syn_offsets se' t' syn_offs'
| _ -> | _ ->
L.d_strln "Failure of get_strexp_at_syn_offsets"; L.d_strln "Failure of get_strexp_at_syn_offsets";
L.d_str "se: "; Sil.d_sexp se; L.d_ln (); L.d_str "se: "; Sil.d_sexp se; L.d_ln ();
L.d_str "t: "; Sil.d_typ_full t; L.d_ln (); L.d_str "t: "; Typ.d_full t; L.d_ln ();
assert false assert false
(** Replace a strexp at the given syntactic offset list *) (** Replace a strexp at the given syntactic offset list *)
@ -87,15 +87,18 @@ end = struct
match se, t, syn_offs with match se, t, syn_offs with
| _, _, [] -> | _, _, [] ->
update se update se
| Sil.Estruct (fsel, inst), Sil.Tstruct { Sil.instance_fields }, Field (fld, _) :: syn_offs' -> | Sil.Estruct (fsel, inst), Typ.Tstruct { Typ.instance_fields }, Field (fld, _) :: syn_offs' ->
let se' = snd (IList.find (fun (f', _) -> Sil.fld_equal f' fld) fsel) in let se' = snd (IList.find (fun (f', _) -> Ident.fieldname_equal f' fld) fsel) in
let t' = (fun (_,y,_) -> y) let t' = (fun (_,y,_) -> y)
(IList.find (fun (f', _, _) -> (IList.find (fun (f', _, _) ->
Sil.fld_equal f' fld) instance_fields) in Ident.fieldname_equal f' fld) instance_fields) in
let se_mod = replace_strexp_at_syn_offsets se' t' syn_offs' update in let se_mod = replace_strexp_at_syn_offsets se' t' syn_offs' update in
let fsel' = IList.map (fun (f'', se'') -> if Sil.fld_equal f'' fld then (fld, se_mod) else (f'', se'')) fsel in let fsel' =
IList.map (fun (f'', se'') ->
if Ident.fieldname_equal f'' fld then (fld, se_mod) else (f'', se'')
) fsel in
Sil.Estruct (fsel', inst) Sil.Estruct (fsel', inst)
| Sil.Earray (len, esel, inst), Sil.Tarray (t', _), Index idx :: syn_offs' -> | Sil.Earray (len, esel, inst), Typ.Tarray (t', _), Index idx :: syn_offs' ->
let se' = snd (IList.find (fun (i', _) -> Sil.exp_equal i' idx) esel) in let se' = snd (IList.find (fun (i', _) -> Sil.exp_equal i' idx) esel) in
let se_mod = replace_strexp_at_syn_offsets se' t' syn_offs' update in let se_mod = replace_strexp_at_syn_offsets se' t' syn_offs' update in
let esel' = IList.map (fun ese -> if Sil.exp_equal (fst ese) idx then (idx, se_mod) else ese) esel in let esel' = IList.map (fun ese -> if Sil.exp_equal (fst ese) idx then (idx, se_mod) else ese) esel in
@ -125,7 +128,7 @@ end = struct
(root, syn_offs) (root, syn_offs)
(** path to the root, len, elements and type of a new_array *) (** path to the root, len, elements and type of a new_array *)
type strexp_data = path * Sil.strexp * Sil.typ type strexp_data = path * Sil.strexp * Typ.t
(** Store hpred using physical equality, and offset list for an array *) (** Store hpred using physical equality, and offset list for an array *)
type t = sigma * Sil.hpred * (syn_offset list) type t = sigma * Sil.hpred * (syn_offset list)
@ -147,9 +150,9 @@ end = struct
if pred (path, se, typ) then found := (sigma, hpred, offs') :: !found if pred (path, se, typ) then found := (sigma, hpred, offs') :: !found
else begin else begin
match se, typ with match se, typ with
| Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields } -> | Sil.Estruct (fsel, _), Typ.Tstruct { Typ.instance_fields } ->
find_offset_fsel sigma_other hpred root offs fsel instance_fields typ find_offset_fsel sigma_other hpred root offs fsel instance_fields typ
| Sil.Earray (_, esel, _), Sil.Tarray (t, _) -> | Sil.Earray (_, esel, _), Typ.Tarray (t, _) ->
find_offset_esel sigma_other hpred root offs esel t find_offset_esel sigma_other hpred root offs esel t
| _ -> () | _ -> ()
end end
@ -158,7 +161,7 @@ end = struct
| (f, se) :: fsel' -> | (f, se) :: fsel' ->
begin begin
try try
let t = (fun (_,y,_) -> y) (IList.find (fun (f', _, _) -> Sil.fld_equal f' f) ftal) in let t = snd3 (IList.find (fun (f', _, _) -> Ident.fieldname_equal f' f) ftal) in
find_offset_sexp sigma_other hpred root ((Field (f, typ)) :: offs) se t find_offset_sexp sigma_other hpred root ((Field (f, typ)) :: offs) se t
with Not_found -> with Not_found ->
L.d_strln ("Can't find field " ^ (Ident.fieldname_to_string f) ^ " in StrexpMatch.find") L.d_strln ("Can't find field " ^ (Ident.fieldname_to_string f) ^ " in StrexpMatch.find")
@ -428,7 +431,7 @@ let keep_only_indices
(** If the type is array, check whether we should do abstraction *) (** If the type is array, check whether we should do abstraction *)
let array_typ_can_abstract = function let array_typ_can_abstract = function
| Sil.Tarray (Sil.Tptr (Sil.Tfun _, _), _) -> false (* don't abstract arrays of pointers *) | Typ.Tarray (Typ.Tptr (Typ.Tfun _, _), _) -> false (* don't abstract arrays of pointers *)
| _ -> true | _ -> true
(** This function checks whether we can apply an abstraction to a strexp *) (** This function checks whether we can apply an abstraction to a strexp *)
@ -524,18 +527,18 @@ let check_after_array_abstraction prop =
let rec check_se root offs typ = function let rec check_se root offs typ = function
| Sil.Eexp _ -> () | Sil.Eexp _ -> ()
| Sil.Earray (_, esel, _) -> (* check that no more than 2 elements are in the array *) | Sil.Earray (_, esel, _) -> (* check that no more than 2 elements are in the array *)
let typ_elem = Sil.array_typ_elem (Some Sil.Tvoid) typ in let typ_elem = Typ.array_elem (Some Typ.Tvoid) typ in
if IList.length esel > 2 && array_typ_can_abstract typ then if IList.length esel > 2 && array_typ_can_abstract typ then
if IList.for_all (check_index root offs) esel then () if IList.for_all (check_index root offs) esel then ()
else report_error prop else report_error prop
else IList.iter (fun (ind, se) -> check_se root (offs @ [Sil.Off_index ind]) typ_elem se) esel else IList.iter (fun (ind, se) -> check_se root (offs @ [Sil.Off_index ind]) typ_elem se) esel
| Sil.Estruct (fsel, _) -> | Sil.Estruct (fsel, _) ->
IList.iter (fun (f, se) -> IList.iter (fun (f, se) ->
let typ_f = Sil.struct_typ_fld (Some Sil.Tvoid) f typ in let typ_f = Typ.struct_typ_fld (Some Typ.Tvoid) f typ in
check_se root (offs @ [Sil.Off_fld (f, typ)]) typ_f se) fsel in check_se root (offs @ [Sil.Off_fld (f, typ)]) typ_f se) fsel in
let check_hpred = function let check_hpred = function
| Sil.Hpointsto (root, se, texp) -> | Sil.Hpointsto (root, se, texp) ->
let typ = Sil.texp_to_typ (Some Sil.Tvoid) texp in let typ = Sil.texp_to_typ (Some Typ.Tvoid) texp in
check_se root [] typ se check_se root [] typ se
| Sil.Hlseg _ | Sil.Hdllseg _ -> () in | Sil.Hlseg _ | Sil.Hdllseg _ -> () in
let check_sigma sigma = IList.iter check_hpred sigma in let check_sigma sigma = IList.iter check_hpred sigma in

@ -275,7 +275,7 @@ end = struct
end end
type varinfo = type varinfo =
{ typ: Sil.typ; (* type of the variable *) { typ: Typ.t; (* type of the variable *)
alloc: bool (* whether the variable needs allocation (on lhs of |->, lists) *) alloc: bool (* whether the variable needs allocation (on lhs of |->, lists) *)
} }
@ -303,23 +303,23 @@ let create_idmap sigma : idmap =
do_exp e2 typ do_exp e2 typ
| Sil.BinOp (Sil.PlusPI, e1, e2), _ -> | Sil.BinOp (Sil.PlusPI, e1, e2), _ ->
do_exp e1 typ; do_exp e1 typ;
do_exp e2 (Sil.Tint Sil.IULong) do_exp e2 (Typ.Tint Typ.IULong)
| Sil.Lfield (e1, _, _), _ -> | Sil.Lfield (e1, _, _), _ ->
do_exp e1 typ do_exp e1 typ
| Sil.Sizeof _, _ -> () | Sil.Sizeof _, _ -> ()
| _ -> | _ ->
L.err "Unmatched exp: %a : %a@." (Sil.pp_exp pe) e (Sil.pp_typ_full pe) typ; L.err "Unmatched exp: %a : %a@." (Sil.pp_exp pe) e (Typ.pp_full pe) typ;
assert false in assert false in
let rec do_se se typ = match se, typ with let rec do_se se typ = match se, typ with
| Sil.Eexp (e, _), _ -> | Sil.Eexp (e, _), _ ->
do_exp e typ do_exp e typ
| Sil.Estruct (fsel, _), Sil.Tstruct { Sil.instance_fields } -> | Sil.Estruct (fsel, _), Typ.Tstruct { Typ.instance_fields } ->
do_struct fsel instance_fields do_struct fsel instance_fields
| Sil.Earray (len, esel, _), Sil.Tarray (typ, _) -> | Sil.Earray (len, esel, _), Typ.Tarray (typ, _) ->
do_se (Sil.Eexp (len, Sil.inst_none)) (Sil.Tint Sil.IULong); do_se (Sil.Eexp (len, Sil.inst_none)) (Typ.Tint Typ.IULong);
do_array esel typ do_array esel typ
| _ -> | _ ->
L.err "Unmatched sexp: %a : %a@." (Sil.pp_sexp pe) se (Sil.pp_typ_full pe) typ; L.err "Unmatched sexp: %a : %a@." (Sil.pp_sexp pe) se (Typ.pp_full pe) typ;
assert false assert false
and do_struct fsel ftal = match fsel, ftal with and do_struct fsel ftal = match fsel, ftal with
| [], _ -> () | [], _ -> ()
@ -331,7 +331,7 @@ let create_idmap sigma : idmap =
| _:: _, [] -> assert false | _:: _, [] -> assert false
and do_array esel typ = match esel with and do_array esel typ = match esel with
| (e, se):: esel' -> | (e, se):: esel' ->
do_se (Sil.Eexp (e, Sil.inst_none)) (Sil.Tint Sil.IULong); do_se (Sil.Eexp (e, Sil.inst_none)) (Typ.Tint Typ.IULong);
do_se se typ; do_se se typ;
do_array esel' typ do_array esel' typ
| [] -> () in | [] -> () in
@ -341,12 +341,12 @@ let create_idmap sigma : idmap =
| _ -> () in | _ -> () in
let do_hpred = function let do_hpred = function
| Sil.Hpointsto (e, se, Sil.Sizeof (typ, _, _)) -> | Sil.Hpointsto (e, se, Sil.Sizeof (typ, _, _)) ->
do_lhs_e e (Sil.Tptr (typ, Sil.Pk_pointer)); do_lhs_e e (Typ.Tptr (typ, Typ.Pk_pointer));
do_se se typ do_se se typ
| Sil.Hlseg (_, _, e, f, el) -> | Sil.Hlseg (_, _, e, f, el) ->
do_lhs_e e (Sil.Tptr (Sil.Tvoid, Sil.Pk_pointer)); do_lhs_e e (Typ.Tptr (Typ.Tvoid, Typ.Pk_pointer));
do_se (Sil.Eexp (f, Sil.inst_none)) (Sil.Tptr (Sil.Tvoid, Sil.Pk_pointer)); do_se (Sil.Eexp (f, Sil.inst_none)) (Typ.Tptr (Typ.Tvoid, Typ.Pk_pointer));
IList.iter (fun e -> do_se (Sil.Eexp (e, Sil.inst_none)) Sil.Tvoid) el IList.iter (fun e -> do_se (Sil.Eexp (e, Sil.inst_none)) Typ.Tvoid) el
| hpred -> | hpred ->
L.err "do_hpred not implemented %a@." (Sil.pp_hpred pe) hpred in L.err "do_hpred not implemented %a@." (Sil.pp_hpred pe) hpred in
IList.iter do_hpred sigma; IList.iter do_hpred sigma;
@ -405,7 +405,7 @@ let rec pp_exp_c pe fmt = function
(** pretty print a type in C *) (** pretty print a type in C *)
let pp_typ_c pe typ = let pp_typ_c pe typ =
let pp_nil _ () = () in let pp_nil _ () = () in
Sil.pp_type_decl pe pp_nil pp_exp_c typ Typ.pp_decl pe pp_nil typ
(** Convert a pvar to a string by just extracting the name *) (** Convert a pvar to a string by just extracting the name *)
let to_string pvar = let to_string pvar =
@ -424,16 +424,16 @@ let mk_size_name id =
let pp_texp_for_malloc fmt = let pp_texp_for_malloc fmt =
let rec handle_arr_len typ = match typ with let rec handle_arr_len typ = match typ with
| Sil.Tvar _ | Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ -> | Typ.Tvar _ | Typ.Tint _ | Typ.Tfloat _ | Typ.Tvoid | Typ.Tfun _ ->
typ typ
| Sil.Tptr (t, pk) -> | Typ.Tptr (t, pk) ->
Sil.Tptr (handle_arr_len t, pk) Typ.Tptr (handle_arr_len t, pk)
| Sil.Tstruct struct_typ -> | Typ.Tstruct struct_typ ->
let instance_fields = let instance_fields =
IList.map (fun (f, t, a) -> (f, handle_arr_len t, a)) struct_typ.Sil.instance_fields in IList.map (fun (f, t, a) -> (f, handle_arr_len t, a)) struct_typ.Typ.instance_fields in
Sil.Tstruct { struct_typ with Sil.instance_fields } Typ.Tstruct { struct_typ with Typ.instance_fields }
| Sil.Tarray (t, e) -> | Typ.Tarray (t, e) ->
Sil.Tarray (handle_arr_len t, e) in Typ.Tarray (handle_arr_len t, e) in
function function
| Sil.Sizeof (typ, _, _) -> | Sil.Sizeof (typ, _, _) ->
let typ' = handle_arr_len typ in let typ' = handle_arr_len typ in
@ -501,11 +501,11 @@ let gen_init_equalities code pure =
let gen_var_decl code idmap parameters = let gen_var_decl code idmap parameters =
let do_parameter (name, typ) = let do_parameter (name, typ) =
let pp_name f () = Mangled.pp f name in let pp_name f () = Mangled.pp f name in
let pp f () = F.fprintf f "%a;" (Sil.pp_type_decl pe pp_name pp_exp_c) typ in let pp f () = F.fprintf f "%a;" (Typ.pp_decl pe pp_name) typ in
Code.add_from_pp code pp in Code.add_from_pp code pp in
let do_vinfo id { typ } = let do_vinfo id { typ } =
let pp_var f () = pp_id_c f id in let pp_var f () = pp_id_c f id in
let pp f () = F.fprintf f "%a;" (Sil.pp_type_decl pe pp_var pp_exp_c) typ in let pp f () = F.fprintf f "%a;" (Typ.pp_decl pe pp_var) typ in
Code.add_from_pp code pp in Code.add_from_pp code pp in
IList.iter do_parameter parameters; IList.iter do_parameter parameters;
IdMap.iter do_vinfo idmap IdMap.iter do_vinfo idmap
@ -518,20 +518,20 @@ let gen_init_vars code solutions idmap =
let do_vinfo id { typ = typ; alloc = alloc } = let do_vinfo id { typ = typ; alloc = alloc } =
if not alloc then if not alloc then
let const = match typ with let const = match typ with
| Sil.Tint _ | Sil.Tvoid -> | Typ.Tint _ | Typ.Tvoid ->
get_const id (Sil.Cint IntLit.zero) get_const id (Sil.Cint IntLit.zero)
| Sil.Tfloat _ -> | Typ.Tfloat _ ->
Sil.Cfloat 0.0 Sil.Cfloat 0.0
| Sil.Tptr _ -> | Typ.Tptr _ ->
get_const id (Sil.Cint IntLit.zero) get_const id (Sil.Cint IntLit.zero)
| Sil.Tfun _ -> | Typ.Tfun _ ->
Sil.Cint IntLit.zero Sil.Cint IntLit.zero
| typ -> | typ ->
L.err "do_vinfo type undefined: %a@." (Sil.pp_typ_full pe) typ; L.err "do_vinfo type undefined: %a@." (Typ.pp_full pe) typ;
assert false in assert false in
let pp fmt () = let pp fmt () =
F.fprintf fmt "%a = (%a) %a;" F.fprintf fmt "%a = (%a) %a;"
pp_id_c id (Sil.pp_typ_full pe) typ (Sil.pp_exp pe) (Sil.Const const) in pp_id_c id (Typ.pp_full pe) typ (Sil.pp_exp pe) (Sil.Const const) in
Code.add_from_pp code pp in Code.add_from_pp code pp in
IdMap.iter do_vinfo idmap IdMap.iter do_vinfo idmap
@ -592,7 +592,7 @@ let gen_hpara code proc_name spec_num env id hpara =
let gen_hpara_dll _ _ _ _ _ _ = assert false let gen_hpara_dll _ _ _ _ _ _ = assert false
(** Generate epilog for the test case *) (** Generate epilog for the test case *)
let gen_epilog code proc_name (parameters : (Mangled.t * Sil.typ) list) = let gen_epilog code proc_name (parameters : (Mangled.t * Typ.t) list) =
let pp_parameter fmt (name, _) = Mangled.pp fmt name in let pp_parameter fmt (name, _) = Mangled.pp fmt name in
let pp f () = F.fprintf f "%a(%a);" Procname.pp proc_name (pp_comma_seq pp_parameter) parameters in let pp f () = F.fprintf f "%a(%a);" Procname.pp proc_name (pp_comma_seq pp_parameter) parameters in
let line1 = pp_to_string pp () in let line1 = pp_to_string pp () in

@ -19,7 +19,7 @@ type code
val pp_code : Format.formatter -> code -> unit val pp_code : Format.formatter -> code -> unit
(** generate a unit test form a spec *) (** generate a unit test form a spec *)
val genunit : string -> Procname.t -> int -> (Mangled.t * Sil.typ) list val genunit : string -> Procname.t -> int -> (Mangled.t * Typ.t) list
-> Prop.normal Specs.spec -> code -> Prop.normal Specs.spec -> code
(** generate code for a main calling all the unit test functions passed as argument *) (** generate code for a main calling all the unit test functions passed as argument *)

@ -18,7 +18,7 @@ type args = {
prop_ : Prop.normal Prop.t; prop_ : Prop.normal Prop.t;
path : Paths.Path.t; path : Paths.Path.t;
ret_ids : Ident.t list; ret_ids : Ident.t list;
args : (Sil.exp * Sil.typ) list; args : (Sil.exp * Typ.t) list;
proc_name : Procname.t; proc_name : Procname.t;
loc : Location.t; loc : Location.t;
} }

@ -18,7 +18,7 @@ type args = {
prop_ : Prop.normal Prop.t; prop_ : Prop.normal Prop.t;
path : Paths.Path.t; path : Paths.Path.t;
ret_ids : Ident.t list; ret_ids : Ident.t list;
args : (Sil.exp * Sil.typ) list; args : (Sil.exp * Typ.t) list;
proc_name : Procname.t; proc_name : Procname.t;
loc : Location.t; loc : Location.t;
} }

@ -928,7 +928,7 @@ let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
let e_res = Rename.extend (Sil.exp_int c1') (Sil.Var id2) Rename.ExtFresh in let e_res = Rename.extend (Sil.exp_int c1') (Sil.Var id2) Rename.ExtFresh in
Sil.BinOp(Sil.PlusA, e_res, Sil.exp_int c2) Sil.BinOp(Sil.PlusA, e_res, Sil.exp_int c2)
| Sil.Cast(t1, e1), Sil.Cast(t2, e2) -> | Sil.Cast(t1, e1), Sil.Cast(t2, e2) ->
if not (Sil.typ_equal t1 t2) then (L.d_strln "failure reason 22"; raise IList.Fail) if not (Typ.equal t1 t2) then (L.d_strln "failure reason 22"; raise IList.Fail)
else else
let e1'' = exp_partial_join e1 e2 in let e1'' = exp_partial_join e1 e2 in
Sil.Cast (t1, e1'') Sil.Cast (t1, e1'')
@ -951,7 +951,7 @@ let rec exp_partial_join (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
if not (Pvar.equal pvar1 pvar2) then (L.d_strln "failure reason 25"; raise IList.Fail) if not (Pvar.equal pvar1 pvar2) then (L.d_strln "failure reason 25"; raise IList.Fail)
else e1 else e1
| Sil.Lfield(e1, f1, t1), Sil.Lfield(e2, f2, _) -> | Sil.Lfield(e1, f1, t1), Sil.Lfield(e2, f2, _) ->
if not (Sil.fld_equal f1 f2) then (L.d_strln "failure reason 26"; raise IList.Fail) if not (Ident.fieldname_equal f1 f2) then (L.d_strln "failure reason 26"; raise IList.Fail)
else Sil.Lfield(exp_partial_join e1 e2, f1, t1) (* should be t1 = t2 *) else Sil.Lfield(exp_partial_join e1 e2, f1, t1) (* should be t1 = t2 *)
| Sil.Lindex(e1, e1'), Sil.Lindex(e2, e2') -> | Sil.Lindex(e1, e1'), Sil.Lindex(e2, e2') ->
let e1'' = exp_partial_join e1 e2 in let e1'' = exp_partial_join e1 e2 in
@ -982,15 +982,16 @@ and dynamic_length_partial_join l1 l2 =
option_partial_join (fun len1 len2 -> Some (length_partial_join len1 len2)) l1 l2 option_partial_join (fun len1 len2 -> Some (length_partial_join len1 len2)) l1 l2
and typ_partial_join t1 t2 = match t1, t2 with and typ_partial_join t1 t2 = match t1, t2 with
| Sil.Tptr (t1, pk1), Sil.Tptr (t2, pk2) when Sil.ptr_kind_compare pk1 pk2 = 0 -> | Typ.Tptr (t1, pk1), Typ.Tptr (t2, pk2) when Typ.ptr_kind_compare pk1 pk2 = 0 ->
Sil.Tptr (typ_partial_join t1 t2, pk1) Typ.Tptr (typ_partial_join t1 t2, pk1)
| Sil.Tarray (typ1, len1), Sil.Tarray (typ2, len2) -> | Typ.Tarray (typ1, len1), Typ.Tarray (typ2, len2) ->
let t = typ_partial_join typ1 typ2 in let t = typ_partial_join typ1 typ2 in
let len = static_length_partial_join len1 len2 in let len = static_length_partial_join len1 len2 in
Sil.Tarray (t, len) Typ.Tarray (t, len)
| _ when Sil.typ_equal t1 t2 -> t1 (* common case *) | _ when Typ.equal t1 t2 -> t1 (* common case *)
| _ -> | _ ->
L.d_str "typ_partial_join no match "; Sil.d_typ_full t1; L.d_str " "; Sil.d_typ_full t2; L.d_ln (); L.d_str "typ_partial_join no match ";
Typ.d_full t1; L.d_str " "; Typ.d_full t2; L.d_ln ();
raise IList.Fail raise IList.Fail
let rec exp_partial_meet (e1: Sil.exp) (e2: Sil.exp) : Sil.exp = let rec exp_partial_meet (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
@ -1008,7 +1009,7 @@ let rec exp_partial_meet (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
| Sil.Const c1, Sil.Const c2 -> | Sil.Const c1, Sil.Const c2 ->
if (Sil.const_equal c1 c2) then e1 else (L.d_strln "failure reason 29"; raise IList.Fail) if (Sil.const_equal c1 c2) then e1 else (L.d_strln "failure reason 29"; raise IList.Fail)
| Sil.Cast(t1, e1), Sil.Cast(t2, e2) -> | Sil.Cast(t1, e1), Sil.Cast(t2, e2) ->
if not (Sil.typ_equal t1 t2) then (L.d_strln "failure reason 30"; raise IList.Fail) if not (Typ.equal t1 t2) then (L.d_strln "failure reason 30"; raise IList.Fail)
else else
let e1'' = exp_partial_meet e1 e2 in let e1'' = exp_partial_meet e1 e2 in
Sil.Cast (t1, e1'') Sil.Cast (t1, e1'')
@ -1033,7 +1034,7 @@ let rec exp_partial_meet (e1: Sil.exp) (e2: Sil.exp) : Sil.exp =
if not (Pvar.equal pvar1 pvar2) then (L.d_strln "failure reason 35"; raise IList.Fail) if not (Pvar.equal pvar1 pvar2) then (L.d_strln "failure reason 35"; raise IList.Fail)
else e1 else e1
| Sil.Lfield(e1, f1, t1), Sil.Lfield(e2, f2, _) -> | Sil.Lfield(e1, f1, t1), Sil.Lfield(e2, f2, _) ->
if not (Sil.fld_equal f1 f2) then (L.d_strln "failure reason 36"; raise IList.Fail) if not (Ident.fieldname_equal f1 f2) then (L.d_strln "failure reason 36"; raise IList.Fail)
else Sil.Lfield(exp_partial_meet e1 e2, f1, t1) (* should be t1 = t2 *) else Sil.Lfield(exp_partial_meet e1 e2, f1, t1) (* should be t1 = t2 *)
| Sil.Lindex(e1, e1'), Sil.Lindex(e2, e2') -> | Sil.Lindex(e1, e1'), Sil.Lindex(e2, e2') ->
let e1'' = exp_partial_meet e1 e2 in let e1'' = exp_partial_meet e1 e2 in
@ -1060,7 +1061,7 @@ let rec strexp_partial_join mode (strexp1: Sil.strexp) (strexp2: Sil.strexp) : S
| JoinState.Post -> Sil.Estruct (IList.rev acc, inst) | JoinState.Post -> Sil.Estruct (IList.rev acc, inst)
end end
| (fld1, se1):: fld_se_list1', (fld2, se2):: fld_se_list2' -> | (fld1, se1):: fld_se_list1', (fld2, se2):: fld_se_list2' ->
let comparison = Sil.fld_compare fld1 fld2 in let comparison = Ident.fieldname_compare fld1 fld2 in
if comparison = 0 then if comparison = 0 then
let strexp' = strexp_partial_join mode se1 se2 in let strexp' = strexp_partial_join mode se1 se2 in
let fld_se_list_new = (fld1, strexp') :: acc in let fld_se_list_new = (fld1, strexp') :: acc in
@ -1124,7 +1125,7 @@ let rec strexp_partial_meet (strexp1: Sil.strexp) (strexp2: Sil.strexp) : Sil.st
| _, [] -> | _, [] ->
Sil.Estruct (construct Lhs acc fld_se_list1, inst) Sil.Estruct (construct Lhs acc fld_se_list1, inst)
| (fld1, se1):: fld_se_list1', (fld2, se2):: fld_se_list2' -> | (fld1, se1):: fld_se_list1', (fld2, se2):: fld_se_list2' ->
let comparison = Sil.fld_compare fld1 fld2 in let comparison = Ident.fieldname_compare fld1 fld2 in
if comparison < 0 then if comparison < 0 then
let se' = strexp_construct_fresh Lhs se1 in let se' = strexp_construct_fresh Lhs se1 in
let acc_new = (fld1, se'):: acc in let acc_new = (fld1, se'):: acc in

@ -66,7 +66,7 @@ type dotty_node =
| Dotstruct of coordinate * Sil.exp * (Ident.fieldname * Sil.strexp) list * string * Sil.exp | Dotstruct of coordinate * Sil.exp * (Ident.fieldname * Sil.strexp) list * string * Sil.exp
(* Dotarray(coo,e1,e2,l,t,c): array box for expression e1 with field list l at coordinate coo and color c*) (* Dotarray(coo,e1,e2,l,t,c): array box for expression e1 with field list l at coordinate coo and color c*)
(* e2 is the len and t is the type *) (* e2 is the len and t is the type *)
| Dotarray of coordinate * Sil.exp * Sil.exp * (Sil.exp * Sil.strexp) list * Sil.typ * string | Dotarray of coordinate * Sil.exp * Sil.exp * (Sil.exp * Sil.strexp) list * Typ.t * string
(* Dotlseg(coo,e1,e2,k,h,c): list box from e1 to e2 at coordinate coo and color c*) (* Dotlseg(coo,e1,e2,k,h,c): list box from e1 to e2 at coordinate coo and color c*)
| Dotlseg of coordinate * Sil.exp * Sil.exp * Sil.lseg_kind * Sil.hpred list * string | Dotlseg of coordinate * Sil.exp * Sil.exp * Sil.lseg_kind * Sil.hpred list * string
(* Dotlseg(coo,e1,e2,e3,e4,k,h,c): doubly linked-list box from with parameters (e1,e2,e3,e4) at coordinate coo and color c*) (* Dotlseg(coo,e1,e2,e3,e4,k,h,c): doubly linked-list box from with parameters (e1,e2,e3,e4) at coordinate coo and color c*)
@ -294,7 +294,7 @@ let rec dotty_mk_node pe sigma =
let n = !dotty_state_count in let n = !dotty_state_count in
incr dotty_state_count; incr dotty_state_count;
let do_hpred_lambda exp_color = function let do_hpred_lambda exp_color = function
| (Sil.Hpointsto (e, Sil.Earray (e', l, _), Sil.Sizeof (Sil.Tarray (t, _), _, _)), lambda) -> | (Sil.Hpointsto (e, Sil.Earray (e', l, _), Sil.Sizeof (Typ.Tarray (t, _), _, _)), lambda) ->
incr dotty_state_count; (* increment once more n+1 is the box for the array *) incr dotty_state_count; (* increment once more n+1 is the box for the array *)
let e_color_str = color_to_str (exp_color e) in let e_color_str = color_to_str (exp_color e) in
let e_color_str'= color_to_str (exp_color e') in let e_color_str'= color_to_str (exp_color e') in
@ -675,7 +675,7 @@ let filter_useless_spec_dollar_box (nodes: dotty_node list) (links: link list) =
let rec print_struct f pe e te l coo c = let rec print_struct f pe e te l coo c =
let print_type = match te with let print_type = match te with
| Sil.Sizeof (t, _, _) -> | Sil.Sizeof (t, _, _) ->
let str_t = Sil.typ_to_string t in let str_t = Typ.to_string t in
(match Str.split_delim (Str.regexp_string Config.anonymous_block_prefix) str_t with (match Str.split_delim (Str.regexp_string Config.anonymous_block_prefix) str_t with
| [_; _] -> "BLOCK object" | [_; _] -> "BLOCK object"
| _ -> str_t) | _ -> str_t)
@ -929,11 +929,11 @@ let pp_cfgnodename fmt (n : Cfg.Node.t) =
let pp_etlist fmt etl = let pp_etlist fmt etl =
IList.iter (fun (id, ty) -> IList.iter (fun (id, ty) ->
Format.fprintf fmt " %a:%a" Mangled.pp id (Sil.pp_typ_full pe_text) ty) etl Format.fprintf fmt " %a:%a" Mangled.pp id (Typ.pp_full pe_text) ty) etl
let pp_local_list fmt etl = let pp_local_list fmt etl =
IList.iter (fun (id, ty) -> IList.iter (fun (id, ty) ->
Format.fprintf fmt " %a:%a" Mangled.pp id (Sil.pp_typ_full pe_text) ty) etl Format.fprintf fmt " %a:%a" Mangled.pp id (Typ.pp_full pe_text) ty) etl
let pp_cfgnodelabel fmt (n : Cfg.Node.t) = let pp_cfgnodelabel fmt (n : Cfg.Node.t) =
let pp_label fmt n = let pp_label fmt n =

@ -23,7 +23,7 @@ type kind_of_dotty_prop =
val reset_proposition_counter : unit -> unit val reset_proposition_counter : unit -> unit
val pp_dotty : Format.formatter -> kind_of_dotty_prop -> Prop.normal Prop.t -> val pp_dotty : Format.formatter -> kind_of_dotty_prop -> Prop.normal Prop.t ->
((Sil.strexp * Sil.typ) * Ident.fieldname * Sil.strexp) list option -> unit ((Sil.strexp * Typ.t) * Ident.fieldname * Sil.strexp) list option -> unit
(** {2 Sets and lists of propositions} *) (** {2 Sets and lists of propositions} *)
@ -47,10 +47,10 @@ val pp_speclist_dotty_file : DB.filename -> Prop.normal Specs.spec list -> unit
(* create a dotty file with a single proposition *) (* create a dotty file with a single proposition *)
val dotty_prop_to_dotty_file : string -> Prop.normal Prop.t -> val dotty_prop_to_dotty_file : string -> Prop.normal Prop.t ->
((Sil.strexp * Sil.typ) * Ident.fieldname * Sil.strexp) list -> unit ((Sil.strexp * Typ.t) * Ident.fieldname * Sil.strexp) list -> unit
val dotty_prop_to_str : Prop.normal Prop.t -> val dotty_prop_to_str : Prop.normal Prop.t ->
((Sil.strexp * Sil.typ) * Ident.fieldname * Sil.strexp) list -> string option ((Sil.strexp * Typ.t) * Ident.fieldname * Sil.strexp) list -> string option
(** reset the counter used for node and heap identifiers *) (** reset the counter used for node and heap identifiers *)
val reset_node_counter : unit -> unit val reset_node_counter : unit -> unit

@ -504,12 +504,12 @@ let explain_leak tenv hpred prop alloc_att_opt bucket =
(Pvar.is_local pvar || Pvar.is_global pvar) && (Pvar.is_local pvar || Pvar.is_global pvar) &&
not (pvar_is_frontend_tmp pvar) && not (pvar_is_frontend_tmp pvar) &&
match hpred_typ_opt, find_typ_without_ptr prop pvar with match hpred_typ_opt, find_typ_without_ptr prop pvar with
| Some (Sil.Sizeof (t1, _, _)), Some (Sil.Sizeof (Sil.Tptr (t2_, _), _, _)) -> | Some (Sil.Sizeof (t1, _, _)), Some (Sil.Sizeof (Typ.Tptr (t2_, _), _, _)) ->
(try (try
let t2 = Tenv.expand_type tenv t2_ in let t2 = Tenv.expand_type tenv t2_ in
Sil.typ_equal t1 t2 Typ.equal t1 t2
with exn when SymOp.exn_not_failure exn -> false) with exn when SymOp.exn_not_failure exn -> false)
| Some (Sil.Sizeof (Sil.Tint _, _, _)), Some (Sil.Sizeof (Sil.Tint _, _, _)) | Some (Sil.Sizeof (Typ.Tint _, _, _)), Some (Sil.Sizeof (Typ.Tint _, _, _))
when is_file -> (* must be a file opened with "open" *) when is_file -> (* must be a file opened with "open" *)
true true
| _ -> false in | _ -> false in
@ -568,7 +568,7 @@ let explain_leak tenv hpred prop alloc_att_opt bucket =
(** find the dexp, if any, where the given value is stored (** find the dexp, if any, where the given value is stored
also return the type of the value if found *) also return the type of the value if found *)
let vpath_find prop _exp : Sil.dexp option * Sil.typ option = let vpath_find prop _exp : Sil.dexp option * Typ.t option =
if verbose then (L.d_str "in vpath_find exp:"; Sil.d_exp _exp; L.d_ln ()); if verbose then (L.d_str "in vpath_find exp:"; Sil.d_exp _exp; L.d_ln ());
let rec find sigma_acc sigma_todo exp = let rec find sigma_acc sigma_todo exp =
let do_fse res sigma_acc' sigma_todo' lexp texp (f, se) = match se with let do_fse res sigma_acc' sigma_todo' lexp texp (f, se) = match se with
@ -577,12 +577,12 @@ let vpath_find prop _exp : Sil.dexp option * Sil.typ option =
(match lexp with (match lexp with
| Sil.Lvar pv -> | Sil.Lvar pv ->
let typo = match texp with let typo = match texp with
| Sil.Sizeof (Sil.Tstruct struct_typ, _, _) -> | Sil.Sizeof (Typ.Tstruct struct_typ, _, _) ->
(try (try
let _, t, _ = let _, t, _ =
IList.find (fun (f', _, _) -> IList.find (fun (f', _, _) ->
Ident.fieldname_equal f' f) Ident.fieldname_equal f' f)
struct_typ.Sil.instance_fields in struct_typ.Typ.instance_fields in
Some t Some t
with Not_found -> None) with Not_found -> None)
| _ -> None in | _ -> None in
@ -650,7 +650,7 @@ let vpath_find prop _exp : Sil.dexp option * Sil.typ option =
| Some de, typo -> L.d_str "vpath_find: found "; L.d_str (Sil.dexp_to_string de); L.d_str " : "; | Some de, typo -> L.d_str "vpath_find: found "; L.d_str (Sil.dexp_to_string de); L.d_str " : ";
match typo with match typo with
| None -> L.d_str " No type" | None -> L.d_str " No type"
| Some typ -> Sil.d_typ_full typ; | Some typ -> Typ.d_full typ;
L.d_ln () L.d_ln ()
end; end;
res res
@ -1057,7 +1057,7 @@ let explain_divide_by_zero exp node loc =
(** explain a return expression required *) (** explain a return expression required *)
let explain_return_expression_required loc typ = let explain_return_expression_required loc typ =
let typ_str = let typ_str =
let pp fmt () = Sil.pp_typ_full pe_text fmt typ in let pp fmt () = Typ.pp_full pe_text fmt typ in
pp_to_string pp () in pp_to_string pp () in
Localise.desc_return_expression_required typ_str loc Localise.desc_return_expression_required typ_str loc
@ -1127,7 +1127,7 @@ let explain_unary_minus_applied_to_unsigned_expression exp typ node loc =
| Some de -> Some (Sil.dexp_to_string de) | Some de -> Some (Sil.dexp_to_string de)
| None -> None in | None -> None in
let typ_str = let typ_str =
let pp fmt () = Sil.pp_typ_full pe_text fmt typ in let pp fmt () = Typ.pp_full pe_text fmt typ in
pp_to_string pp () in pp_to_string pp () in
Localise.desc_unary_minus_applied_to_unsigned_expression exp_str_opt typ_str loc Localise.desc_unary_minus_applied_to_unsigned_expression exp_str_opt typ_str loc

@ -14,7 +14,7 @@ open! Utils
(** find the dexp, if any, where the given value is stored (** find the dexp, if any, where the given value is stored
also return the type of the value if found *) also return the type of the value if found *)
val vpath_find : 'a Prop.t -> Sil.exp -> Sil.vpath * Sil.typ option val vpath_find : 'a Prop.t -> Sil.exp -> Sil.vpath * Typ.t option
(** Return true if [id] is assigned to a program variable which is then nullified *) (** Return true if [id] is assigned to a program variable which is then nullified *)
val id_is_assigned_then_dead : Cfg.Node.t -> Ident.t -> bool val id_is_assigned_then_dead : Cfg.Node.t -> Ident.t -> bool
@ -41,8 +41,8 @@ val find_boolean_assignment : Cfg.Node.t -> Pvar.t -> bool -> Cfg.Node.t option
val exp_rv_dexp : Cfg.Node.t -> Sil.exp -> Sil.dexp option val exp_rv_dexp : Cfg.Node.t -> Sil.exp -> Sil.dexp option
(** Produce a description of a persistent reference to an Android Context *) (** Produce a description of a persistent reference to an Android Context *)
val explain_context_leak : Procname.t -> Sil.typ -> Ident.fieldname -> val explain_context_leak : Procname.t -> Typ.t -> Ident.fieldname ->
(Ident.fieldname option * Sil.typ) list -> Localise.error_desc (Ident.fieldname option * Typ.t) list -> Localise.error_desc
(** Produce a description of a pointer dangerously coerced to a boolean in a comparison *) (** Produce a description of a pointer dangerously coerced to a boolean in a comparison *)
val explain_bad_pointer_comparison : Sil.exp -> Cfg.Node.t -> Location.t -> Localise.error_desc val explain_bad_pointer_comparison : Sil.exp -> Cfg.Node.t -> Location.t -> Localise.error_desc
@ -80,7 +80,7 @@ val explain_dereference_as_caller_expression :
val explain_divide_by_zero : Sil.exp -> Cfg.Node.t -> Location.t -> Localise.error_desc val explain_divide_by_zero : Sil.exp -> Cfg.Node.t -> Location.t -> Localise.error_desc
(** explain a return expression required *) (** explain a return expression required *)
val explain_return_expression_required : Location.t -> Sil.typ -> Localise.error_desc val explain_return_expression_required : Location.t -> Typ.t -> Localise.error_desc
(** explain a comparing floats for equality *) (** explain a comparing floats for equality *)
val explain_comparing_floats_for_equality : Location.t -> Localise.error_desc val explain_comparing_floats_for_equality : Location.t -> Localise.error_desc
@ -104,12 +104,12 @@ val explain_return_statement_missing : Location.t -> Localise.error_desc
(** explain a retain cycle *) (** explain a retain cycle *)
val explain_retain_cycle : val explain_retain_cycle :
Prop.normal Prop.t -> ((Sil.strexp * Sil.typ) * Ident.fieldname * Sil.strexp) list -> Prop.normal Prop.t -> ((Sil.strexp * Typ.t) * Ident.fieldname * Sil.strexp) list ->
Location.t -> string option -> Localise.error_desc Location.t -> string option -> Localise.error_desc
(** explain unary minus applied to unsigned expression *) (** explain unary minus applied to unsigned expression *)
val explain_unary_minus_applied_to_unsigned_expression : val explain_unary_minus_applied_to_unsigned_expression :
Sil.exp -> Sil.typ -> Cfg.Node.t -> Location.t -> Localise.error_desc Sil.exp -> Typ.t -> Cfg.Node.t -> Location.t -> Localise.error_desc
(** Explain a tainted value error *) (** Explain a tainted value error *)
val explain_tainted_value_reaching_sensitive_function : val explain_tainted_value_reaching_sensitive_function :

@ -632,7 +632,7 @@ let report_context_leaks pname sigma tenv =
| Some path -> path | Some path -> path
| None -> assert false in (* a path must exist in order for a leak to be reported *) | None -> assert false in (* a path must exist in order for a leak to be reported *)
let err_desc = let err_desc =
Errdesc.explain_context_leak pname (Sil.Tstruct struct_typ) fld_name leak_path in Errdesc.explain_context_leak pname (Typ.Tstruct struct_typ) fld_name leak_path in
let exn = Exceptions.Context_leak (err_desc, __POS__) in let exn = Exceptions.Context_leak (err_desc, __POS__) in
Reporting.log_error pname exn) Reporting.log_error pname exn)
context_exps in context_exps in

@ -244,14 +244,14 @@ let by_call_to_ra tags ra =
"by " ^ call_to_at_line tags ra.Sil.ra_pname ra.Sil.ra_loc "by " ^ call_to_at_line tags ra.Sil.ra_pname ra.Sil.ra_loc
let rec format_typ = function let rec format_typ = function
| Sil.Tptr (typ, _) when !Config.curr_language = Config.Java -> | Typ.Tptr (typ, _) when !Config.curr_language = Config.Java ->
format_typ typ format_typ typ
| Sil.Tstruct { Sil.struct_name = Some name } -> | Typ.Tstruct { Typ.struct_name = Some name } ->
Mangled.to_string name Mangled.to_string name
| Sil.Tvar tname -> | Typ.Tvar tname ->
Typename.name tname Typename.name tname
| typ -> | typ ->
Sil.typ_to_string typ Typ.to_string typ
let format_field f = let format_field f =
if !Config.curr_language = Config.Java if !Config.curr_language = Config.Java
@ -360,7 +360,7 @@ let deref_str_dangling dangling_kind_opt =
(** dereference strings for a pointer size mismatch *) (** dereference strings for a pointer size mismatch *)
let deref_str_pointer_size_mismatch typ_from_instr typ_of_object = let deref_str_pointer_size_mismatch typ_from_instr typ_of_object =
let str_from_typ typ = let str_from_typ typ =
let pp f () = Sil.pp_typ_full pe_text f typ in let pp f () = Typ.pp_full pe_text f typ in
pp_to_string pp () in pp_to_string pp () in
{ tags = Tags.create (); { tags = Tags.create ();
value_pre = Some (pointer_or_object ()); value_pre = Some (pointer_or_object ());
@ -413,10 +413,10 @@ let desc_context_leak pname context_typ fieldname leak_path : error_desc =
let leak_path_entry_to_str acc entry = let leak_path_entry_to_str acc entry =
let entry_str = match entry with let entry_str = match entry with
| (Some fld, _) -> Ident.fieldname_to_string fld | (Some fld, _) -> Ident.fieldname_to_string fld
| (None, typ) -> Sil.typ_to_string typ in | (None, typ) -> Typ.to_string typ in
(* intentionally omit space; [typ_to_string] adds an extra space *) (* intentionally omit space; [typ_to_string] adds an extra space *)
acc ^ entry_str ^ " |->\n " in acc ^ entry_str ^ " |->\n " in
let context_str = Sil.typ_to_string context_typ in let context_str = Typ.to_string context_typ in
let path_str = let path_str =
let path_prefix = let path_prefix =
if leak_path = [] then "Leaked " if leak_path = [] then "Leaked "
@ -684,9 +684,9 @@ let desc_leak hpred_type_opt value_str_opt resource_opt resource_action_opt loc
s, " to ", " on " in s, " to ", " on " in
let typ_str = let typ_str =
match hpred_type_opt with match hpred_type_opt with
| Some (Sil.Sizeof (Sil.Tstruct | Some (Sil.Sizeof (Typ.Tstruct
{ Sil.csu = Csu.Class _; { Typ.csu = Csu.Class _;
Sil.struct_name = Some classname; Typ.struct_name = Some classname;
}, _, _)) -> }, _, _)) ->
" of type " ^ Mangled.to_string classname ^ " " " of type " ^ Mangled.to_string classname ^ " "
| _ -> " " in | _ -> " " in
@ -773,7 +773,11 @@ let desc_retain_cycle prop cycle loc cycle_dotty =
str_cycle:=!str_cycle^" ("^(string_of_int !ct)^") object "^e_str^" retaining "^e_str^"."^(Ident.fieldname_to_string f)^", "; str_cycle:=!str_cycle^" ("^(string_of_int !ct)^") object "^e_str^" retaining "^e_str^"."^(Ident.fieldname_to_string f)^", ";
ct:=!ct +1 ct:=!ct +1
| Sil.Eexp (Sil.Sizeof (typ, _, _), _) -> | Sil.Eexp (Sil.Sizeof (typ, _, _), _) ->
str_cycle:=!str_cycle^" ("^(string_of_int !ct)^") an object of "^(Sil.typ_to_string typ)^" retaining another object via instance variable "^(Ident.fieldname_to_string f)^", "; let step =
" (" ^ (string_of_int !ct) ^ ") an object of "
^ (Typ.to_string typ) ^ " retaining another object via instance variable "
^ (Ident.fieldname_to_string f) ^ ", " in
str_cycle := !str_cycle ^ step;
ct:=!ct +1 ct:=!ct +1
| _ -> () in | _ -> () in
IList.iter do_edge cycle; IList.iter do_edge cycle;

@ -165,7 +165,7 @@ val deref_str_uninitialized : Sil.attribute option -> deref_str
val deref_str_nil_argument_in_variadic_method : Procname.t -> int -> int -> deref_str val deref_str_nil_argument_in_variadic_method : Procname.t -> int -> int -> deref_str
(** dereference strings for a pointer size mismatch *) (** dereference strings for a pointer size mismatch *)
val deref_str_pointer_size_mismatch : Sil.typ -> Sil.typ -> deref_str val deref_str_pointer_size_mismatch : Typ.t -> Typ.t -> deref_str
(** type of access *) (** type of access *)
type access = type access =
@ -218,11 +218,11 @@ val desc_null_test_after_dereference : string -> int -> Location.t -> error_desc
val java_unchecked_exn_desc : Procname.t -> Typename.t -> string -> error_desc val java_unchecked_exn_desc : Procname.t -> Typename.t -> string -> error_desc
val desc_context_leak : val desc_context_leak :
Procname.t -> Sil.typ -> Ident.fieldname -> Procname.t -> Typ.t -> Ident.fieldname ->
(Ident.fieldname option * Sil.typ) list -> error_desc (Ident.fieldname option * Typ.t) list -> error_desc
val desc_fragment_retains_view : val desc_fragment_retains_view :
Sil.typ -> Ident.fieldname -> Sil.typ -> Procname.t -> error_desc Typ.t -> Ident.fieldname -> Typ.t -> Procname.t -> error_desc
(* Create human-readable error description for assertion failures *) (* Create human-readable error description for assertion failures *)
val desc_custom_error : Location.t -> error_desc val desc_custom_error : Location.t -> error_desc
@ -238,7 +238,7 @@ val desc_precondition_not_met : pnm_kind option -> Procname.t -> Location.t -> e
val desc_return_expression_required : string -> Location.t -> error_desc val desc_return_expression_required : string -> Location.t -> error_desc
val desc_retain_cycle : val desc_retain_cycle :
Prop.normal Prop.t -> ((Sil.strexp * Sil.typ) * Ident.fieldname * Sil.strexp) list -> Prop.normal Prop.t -> ((Sil.strexp * Typ.t) * Ident.fieldname * Sil.strexp) list ->
Location.t -> string option -> error_desc Location.t -> string option -> error_desc
val registered_observer_being_deallocated_str : string -> string val registered_observer_being_deallocated_str : string -> string

@ -70,7 +70,7 @@ let rec exp_match e1 sub vars e2 : (Sil.subst * Ident.t list) option =
None (* Naive *) None (* Naive *)
| Sil.Lvar _, _ | _, Sil.Lvar _ -> | Sil.Lvar _, _ | _, Sil.Lvar _ ->
check_equal sub vars e1 e2 check_equal sub vars e1 e2
| Sil.Lfield(e1', fld1, _), Sil.Lfield(e2', fld2, _) when (Sil.fld_equal fld1 fld2) -> | Sil.Lfield(e1', fld1, _), Sil.Lfield(e2', fld2, _) when (Ident.fieldname_equal fld1 fld2) ->
exp_match e1' sub vars e2' exp_match e1' sub vars e2'
| Sil.Lfield _, _ | _, Sil.Lfield _ -> | Sil.Lfield _, _ | _, Sil.Lfield _ ->
None None
@ -117,7 +117,7 @@ and fsel_match fsel1 sub vars fsel2 =
if (Config.abs_struct <= 0) then None if (Config.abs_struct <= 0) then None
else Some (sub, vars) (* This can lead to great information loss *) else Some (sub, vars) (* This can lead to great information loss *)
| (fld1, se1') :: fsel1', (fld2, se2') :: fsel2' -> | (fld1, se1') :: fsel1', (fld2, se2') :: fsel2' ->
let n = Sil.fld_compare fld1 fld2 in let n = Ident.fieldname_compare fld1 fld2 in
if (n = 0) then begin if (n = 0) then begin
match strexp_match se1' sub vars se2' with match strexp_match se1' sub vars se2' with
| None -> None | None -> None
@ -513,7 +513,7 @@ and generate_todos_from_fel mode todos fel1 fel2 =
| _, [] -> | _, [] ->
if mode == LFieldForget then Some todos else None if mode == LFieldForget then Some todos else None
| (fld1, strexp1) :: fel1', (fld2, strexp2) :: fel2' -> | (fld1, strexp1) :: fel1', (fld2, strexp2) :: fel2' ->
let n = Sil.fld_compare fld1 fld2 in let n = Ident.fieldname_compare fld1 fld2 in
if (n = 0) then if (n = 0) then
begin begin
match generate_todos_from_strexp mode todos strexp1 strexp2 with match generate_todos_from_strexp mode todos strexp1 strexp2 with

@ -17,7 +17,7 @@ val objc_arc_flag : string
(* If cf is passed, then check leaks from Core Foundation. *) (* If cf is passed, then check leaks from Core Foundation. *)
(* If arc is passed, check leaks from code that compiles with arc*) (* If arc is passed, check leaks from code that compiles with arc*)
(* If no arc is passed check the leaks from code that compiles without arc *) (* If no arc is passed check the leaks from code that compiles without arc *)
val should_raise_objc_leak : Sil.typ -> string option val should_raise_objc_leak : Typ.t -> string option
(* Returns whether a memory leak should be raised for a C++ object.*) (* Returns whether a memory leak should be raised for a C++ object.*)
(* If ml_buckets contains cpp, then check leaks from C++ objects. *) (* If ml_buckets contains cpp, then check leaks from C++ objects. *)

@ -40,12 +40,12 @@ let mk_empty_array_rearranged len =
let extract_array_type typ = let extract_array_type typ =
if (!Config.curr_language = Config.Java) then if (!Config.curr_language = Config.Java) then
match typ with match typ with
| Sil.Tptr (Sil.Tarray _ as arr, _) -> Some arr | Typ.Tptr (Typ.Tarray _ as arr, _) -> Some arr
| _ -> None | _ -> None
else else
match typ with match typ with
| Sil.Tarray _ as arr -> Some arr | Typ.Tarray _ as arr -> Some arr
| Sil.Tptr (elt, _) -> Some (Sil.Tarray (elt, None)) | Typ.Tptr (elt, _) -> Some (Typ.Tarray (elt, None))
| _ -> None | _ -> None
(** Return a result from a procedure call. *) (** Return a result from a procedure call. *)
@ -152,13 +152,13 @@ let create_type tenv n_lexp typ prop =
with Not_found -> with Not_found ->
let mhpred = let mhpred =
match typ with match typ with
| Sil.Tptr (typ', _) -> | Typ.Tptr (typ', _) ->
let sexp = Sil.Estruct ([], Sil.inst_none) in let sexp = Sil.Estruct ([], Sil.inst_none) in
let typ'' = Tenv.expand_type tenv typ' in let typ'' = Tenv.expand_type tenv typ' in
let texp = Sil.Sizeof (typ'', None, Sil.Subtype.subtypes) in let texp = Sil.Sizeof (typ'', None, Sil.Subtype.subtypes) in
let hpred = Prop.mk_ptsto n_lexp sexp texp in let hpred = Prop.mk_ptsto n_lexp sexp texp in
Some hpred Some hpred
| Sil.Tarray _ -> | Typ.Tarray _ ->
let len = Sil.Var (Ident.create_fresh Ident.kfootprint) in let len = Sil.Var (Ident.create_fresh Ident.kfootprint) in
let sexp = mk_empty_array len in let sexp = mk_empty_array len in
let texp = Sil.Sizeof (typ, None, Sil.Subtype.subtypes) in let texp = Sil.Sizeof (typ, None, Sil.Subtype.subtypes) in
@ -237,7 +237,7 @@ let execute___instanceof_cast ~instof
let texp2, prop = check_arith_norm_exp pname texp2_ prop__ in let texp2, prop = check_arith_norm_exp pname texp2_ prop__ in
let is_cast_to_reference = let is_cast_to_reference =
match typ1 with match typ1 with
| Sil.Tptr (_, Sil.Pk_reference) -> true | Typ.Tptr (_, Typ.Pk_reference) -> true
| _ -> false in | _ -> false in
(* In Java, we throw an exception, in C++ we return 0 in case of a cast to a pointer, *) (* In Java, we throw an exception, in C++ we return 0 in case of a cast to a pointer, *)
(* and throw an exception in case of a cast to a reference. *) (* and throw an exception in case of a cast to a reference. *)
@ -462,12 +462,12 @@ let execute___objc_counter_update
match args with match args with
| [(lexp, typ)] -> | [(lexp, typ)] ->
let typ' = (match Tenv.expand_type tenv typ with let typ' = (match Tenv.expand_type tenv typ with
| Sil.Tstruct _ as s -> s | Typ.Tstruct _ as s -> s
| Sil.Tptr(t, _) -> Tenv.expand_type tenv t | Typ.Tptr(t, _) -> Tenv.expand_type tenv t
| s' -> | s' ->
L.d_str L.d_str
("Trying to update hidden field of not a struc. Type: " ^ ("Trying to update hidden field of not a struc. Type: " ^
(Sil.typ_to_string s')); (Typ.to_string s'));
assert false) in assert false) in
(* Assumes that lexp is a temp n$1 that has the value of the object. *) (* Assumes that lexp is a temp n$1 that has the value of the object. *)
(* This is the case as a call f(o) it's translates as n$1=*&o; f(n$1) *) (* This is the case as a call f(o) it's translates as n$1=*&o; f(n$1) *)
@ -492,7 +492,7 @@ let execute___objc_counter_update
removed from the list of args. *) removed from the list of args. *)
let get_suppress_npe_flag args = let get_suppress_npe_flag args =
match args with match args with
| (Sil.Const (Sil.Cint i), Sil.Tint Sil.IBool):: args' when IntLit.isone i -> | (Sil.Const (Sil.Cint i), Typ.Tint Typ.IBool):: args' when IntLit.isone i ->
false, args' (* this is a CFRelease/CFRetain *) false, args' (* this is a CFRelease/CFRetain *)
| _ -> true, args | _ -> true, args
@ -758,15 +758,15 @@ let execute_alloc mk can_return_null
| Sil.BinOp (bop, e1', e2') -> | Sil.BinOp (bop, e1', e2') ->
Sil.BinOp (bop, evaluate_char_sizeof e1', evaluate_char_sizeof e2') Sil.BinOp (bop, evaluate_char_sizeof e1', evaluate_char_sizeof e2')
| Sil.Const _ | Sil.Cast _ | Sil.Lvar _ | Sil.Lfield _ | Sil.Lindex _ -> e | Sil.Const _ | Sil.Cast _ | Sil.Lvar _ | Sil.Lfield _ | Sil.Lindex _ -> e
| Sil.Sizeof (Sil.Tarray (Sil.Tint ik, _), Some len, _) when Sil.ikind_is_char ik -> | Sil.Sizeof (Typ.Tarray (Typ.Tint ik, _), Some len, _) when Typ.ikind_is_char ik ->
evaluate_char_sizeof len evaluate_char_sizeof len
| Sil.Sizeof (Sil.Tarray (Sil.Tint ik, Some len), None, _) when Sil.ikind_is_char ik -> | Sil.Sizeof (Typ.Tarray (Typ.Tint ik, Some len), None, _) when Typ.ikind_is_char ik ->
evaluate_char_sizeof (Sil.Const (Sil.Cint len)) evaluate_char_sizeof (Sil.Const (Sil.Cint len))
| Sil.Sizeof _ -> e in | Sil.Sizeof _ -> e in
let size_exp, procname = match args with let size_exp, procname = match args with
| [(Sil.Sizeof | [(Sil.Sizeof
(Sil.Tstruct (Typ.Tstruct
{ Sil.csu = Csu.Class Csu.Objc; struct_name = Some c } as s, len, subt), _)] -> { Typ.csu = Csu.Class Csu.Objc; struct_name = Some c } as s, len, subt), _)] ->
let struct_type = let struct_type =
match AttributesTable.get_correct_type_from_objc_class_name c with match AttributesTable.get_correct_type_from_objc_class_name c with
| Some struct_type -> struct_type | Some struct_type -> struct_type
@ -786,7 +786,7 @@ let execute_alloc mk can_return_null
let n_size_exp' = evaluate_char_sizeof n_size_exp in let n_size_exp' = evaluate_char_sizeof n_size_exp in
Prop.exp_normalize_prop prop n_size_exp', prop in Prop.exp_normalize_prop prop n_size_exp', prop in
let cnt_te = let cnt_te =
Sil.Sizeof (Sil.Tarray (Sil.Tint Sil.IChar, None), Some size_exp', Sil.Subtype.exact) in Sil.Sizeof (Typ.Tarray (Typ.Tint Typ.IChar, None), Some size_exp', Sil.Subtype.exact) in
let id_new = Ident.create_fresh Ident.kprimed in let id_new = Ident.create_fresh Ident.kprimed in
let exp_new = Sil.Var id_new in let exp_new = Sil.Var id_new in
let ptsto_new = let ptsto_new =
@ -825,8 +825,8 @@ let execute___cxx_typeid ({ Builtin.pdesc; tenv; prop_; args; loc} as r)
| Sil.Hpointsto (_, _, Sil.Sizeof (dynamic_type, _, _)) -> dynamic_type | Sil.Hpointsto (_, _, Sil.Sizeof (dynamic_type, _, _)) -> dynamic_type
| _ -> typ | _ -> typ
with Not_found -> typ in with Not_found -> typ in
let typ_string = Sil.typ_to_string typ in let typ_string = Typ.to_string typ in
let set_instr = Sil.Set (field_exp, Sil.Tvoid, Sil.Const (Sil.Cstr typ_string), loc) in let set_instr = Sil.Set (field_exp, Typ.Tvoid, Sil.Const (Sil.Cstr typ_string), loc) in
SymExec.instrs ~mask_errors:true tenv pdesc [set_instr] res SymExec.instrs ~mask_errors:true tenv pdesc [set_instr] res
| _ -> res) | _ -> res)
| _ -> raise (Exceptions.Wrong_argument_number __POS__) | _ -> raise (Exceptions.Wrong_argument_number __POS__)
@ -867,7 +867,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
Sil.item_annotation_empty Typ.item_annotation_empty
{ call_args with args = !varargs } { call_args with args = !varargs }
| _ -> raise (Exceptions.Wrong_argument_number __POS__) | _ -> raise (Exceptions.Wrong_argument_number __POS__)
@ -942,7 +942,7 @@ let execute___infer_fail { Builtin.pdesc; tenv; prop_; path; args; loc; }
| _ -> | _ ->
raise (Exceptions.Wrong_argument_number __POS__) in raise (Exceptions.Wrong_argument_number __POS__) in
let set_instr = let set_instr =
Sil.Set (Sil.Lvar Sil.custom_error, Sil.Tvoid, Sil.Const (Sil.Cstr error_str), loc) in Sil.Set (Sil.Lvar Sil.custom_error, Typ.Tvoid, Sil.Const (Sil.Cstr error_str), loc) in
SymExec.instrs ~mask_errors:true tenv pdesc [set_instr] [(prop_, path)] SymExec.instrs ~mask_errors:true tenv pdesc [set_instr] [(prop_, path)]
(* translate builtin assertion failure *) (* translate builtin assertion failure *)
@ -955,7 +955,7 @@ let execute___assert_fail { Builtin.pdesc; tenv; prop_; path; args; loc; }
| _ -> | _ ->
raise (Exceptions.Wrong_argument_number __POS__) in raise (Exceptions.Wrong_argument_number __POS__) in
let set_instr = let set_instr =
Sil.Set (Sil.Lvar Sil.custom_error, Sil.Tvoid, Sil.Const (Sil.Cstr error_str), loc) in Sil.Set (Sil.Lvar Sil.custom_error, Typ.Tvoid, Sil.Const (Sil.Cstr error_str), loc) in
SymExec.instrs ~mask_errors:true tenv pdesc [set_instr] [(prop_, path)] SymExec.instrs ~mask_errors:true tenv pdesc [set_instr] [(prop_, path)]
let __assert_fail = Builtin.register let __assert_fail = Builtin.register
@ -1156,11 +1156,11 @@ let execute_objc_alloc_no_fail
symb_state typ alloc_fun_opt symb_state typ alloc_fun_opt
{ Builtin.pdesc; tenv; ret_ids; loc; } = { Builtin.pdesc; tenv; ret_ids; loc; } =
let alloc_fun = Sil.Const (Sil.Cfun __objc_alloc_no_fail) in let alloc_fun = Sil.Const (Sil.Cfun __objc_alloc_no_fail) in
let ptr_typ = Sil.Tptr (typ, Sil.Pk_pointer) in let ptr_typ = Typ.Tptr (typ, Typ.Pk_pointer) in
let sizeof_typ = Sil.Sizeof (typ, None, Sil.Subtype.exact) in let sizeof_typ = Sil.Sizeof (typ, None, Sil.Subtype.exact) in
let alloc_fun_exp = let alloc_fun_exp =
match alloc_fun_opt with match alloc_fun_opt with
| Some pname -> [Sil.Const (Sil.Cfun pname), Sil.Tvoid] | Some pname -> [Sil.Const (Sil.Cfun pname), Typ.Tvoid]
| None -> [] in | None -> [] in
let alloc_instr = let alloc_instr =
Sil.Call (ret_ids, alloc_fun, [(sizeof_typ, ptr_typ)] @ alloc_fun_exp, loc, Sil.cf_default) in Sil.Call (ret_ids, alloc_fun, [(sizeof_typ, ptr_typ)] @ alloc_fun_exp, loc, Sil.cf_default) in
@ -1180,7 +1180,7 @@ let arrayWithObjectsCount_pname = mk_objc_class_method "NSArray" "arrayWithObjec
let execute_objc_NSArray_alloc_no_fail let execute_objc_NSArray_alloc_no_fail
({ Builtin.tenv; } as builtin_args) symb_state pname = ({ Builtin.tenv; } as builtin_args) symb_state pname =
let nsarray_typ_ = let nsarray_typ_ =
Sil.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string "NSArray")) in Typ.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string "NSArray")) in
let nsarray_typ = Tenv.expand_type tenv nsarray_typ_ in let nsarray_typ = Tenv.expand_type tenv nsarray_typ_ in
execute_objc_alloc_no_fail symb_state nsarray_typ (Some pname) builtin_args execute_objc_alloc_no_fail symb_state nsarray_typ (Some pname) builtin_args
@ -1204,7 +1204,7 @@ let execute_objc_NSDictionary_alloc_no_fail
symb_state pname symb_state pname
({ Builtin.tenv; } as builtin_args) = ({ Builtin.tenv; } as builtin_args) =
let nsdictionary_typ_ = let nsdictionary_typ_ =
Sil.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string "NSDictionary")) in Typ.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string "NSDictionary")) in
let nsdictionary_typ = let nsdictionary_typ =
Tenv.expand_type tenv nsdictionary_typ_ in Tenv.expand_type tenv nsdictionary_typ_ in
execute_objc_alloc_no_fail symb_state nsdictionary_typ (Some pname) builtin_args execute_objc_alloc_no_fail symb_state nsdictionary_typ (Some pname) builtin_args

@ -206,10 +206,10 @@ struct
let rec is_core_lib lib typ = let rec is_core_lib lib typ =
match typ with match typ with
| Sil.Tptr (styp, _ ) -> | Typ.Tptr (styp, _ ) ->
is_core_lib lib styp is_core_lib lib styp
| Sil.Tvar (Typename.TN_csu (_, name) ) | Typ.Tvar (Typename.TN_csu (_, name) )
| Sil.Tstruct { Sil.struct_name = Some name } -> | Typ.Tstruct { Typ.struct_name = Some name } ->
let core_lib_types = core_lib_to_type_list lib in let core_lib_types = core_lib_to_type_list lib in
IList.mem (=) (Mangled.to_string name) core_lib_types IList.mem (=) (Mangled.to_string name) core_lib_types
| _ -> false | _ -> false

@ -20,7 +20,7 @@ sig
val is_core_lib_release : string -> string -> bool val is_core_lib_release : string -> string -> bool
val is_core_lib_create : Sil.typ -> string -> bool val is_core_lib_create : Typ.t -> string -> bool
val is_core_lib_retain : string -> string -> bool val is_core_lib_retain : string -> string -> bool
@ -31,4 +31,4 @@ sig
end end
val is_core_lib_type : Sil.typ -> bool val is_core_lib_type : Typ.t -> bool

@ -30,7 +30,7 @@ let add_dispatch_calls pdesc cg tenv =
(* the frontend should not populate the list of targets *) (* the frontend should not populate the list of targets *)
assert (call_flags.Sil.cf_targets = []); assert (call_flags.Sil.cf_targets = []);
let receiver_typ_no_ptr = match receiver_typ with let receiver_typ_no_ptr = match receiver_typ with
| Sil.Tptr (typ', _) -> | Typ.Tptr (typ', _) ->
typ' typ'
| _ -> | _ ->
receiver_typ in receiver_typ in

@ -306,11 +306,11 @@ let force_delayed_print fmt =
let (te: Sil.exp) = Obj.obj te in let (te: Sil.exp) = Obj.obj te in
Sil.pp_texp_full pe_default fmt te Sil.pp_texp_full pe_default fmt te
| (L.PTtyp_full, t) -> | (L.PTtyp_full, t) ->
let (t: Sil.typ) = Obj.obj t in let (t: Typ.t) = Obj.obj t in
Sil.pp_typ_full pe_default fmt t Typ.pp_full pe_default fmt t
| (L.PTtyp_list, tl) -> | (L.PTtyp_list, tl) ->
let (tl: Sil.typ list) = Obj.obj tl in let (tl: Typ.t list) = Obj.obj tl in
(pp_seq (Sil.pp_typ pe_default)) fmt tl (pp_seq (Typ.pp pe_default)) fmt tl
| (L.PTerror, s) -> | (L.PTerror, s) ->
let (s: string) = Obj.obj s in let (s: string) = Obj.obj s in
if Config.write_html if Config.write_html

@ -456,11 +456,11 @@ let sym_eval abs e =
Sil.Const (Sil.Cclosure { c with captured_vars; }) Sil.Const (Sil.Cclosure { c with captured_vars; })
| Sil.Const _ -> | Sil.Const _ ->
e e
| Sil.Sizeof (Sil.Tarray (Sil.Tint ik, _), Some l, _) | Sil.Sizeof (Typ.Tarray (Typ.Tint ik, _), Some l, _)
when Sil.ikind_is_char ik && !Config.curr_language = Config.Clang -> when Typ.ikind_is_char ik && !Config.curr_language = Config.Clang ->
eval l eval l
| Sil.Sizeof (Sil.Tarray (Sil.Tint ik, Some l), _, _) | Sil.Sizeof (Typ.Tarray (Typ.Tint ik, Some l), _, _)
when Sil.ikind_is_char ik && !Config.curr_language = Config.Clang -> when Typ.ikind_is_char ik && !Config.curr_language = Config.Clang ->
Sil.Const (Sil.Cint l) Sil.Const (Sil.Cint l)
| Sil.Sizeof _ -> | Sil.Sizeof _ ->
e e
@ -610,7 +610,7 @@ let sym_eval abs e =
| _ -> Sil.BinOp (ominus, x, y) in | _ -> Sil.BinOp (ominus, x, y) in
(* test if the extensible array at the end of [typ] has elements of type [elt] *) (* test if the extensible array at the end of [typ] has elements of type [elt] *)
let extensible_array_element_typ_equal elt typ = let extensible_array_element_typ_equal elt typ =
Option.map_default (Sil.typ_equal elt) false (Sil.get_extensible_array_element_typ typ) in Option.map_default (Typ.equal elt) false (Typ.get_extensible_array_element_typ typ) in
begin begin
match e1', e2' with match e1', e2' with
(* pattern for arrays and extensible structs: (* pattern for arrays and extensible structs:
@ -729,13 +729,13 @@ let sym_eval abs e =
Sil.exp_int (IntLit.div n m) Sil.exp_int (IntLit.div n m)
| Sil.Const (Sil.Cfloat v), Sil.Const (Sil.Cfloat w) -> | Sil.Const (Sil.Cfloat v), Sil.Const (Sil.Cfloat w) ->
Sil.exp_float (v /.w) Sil.exp_float (v /.w)
| Sil.Sizeof (Sil.Tarray (elt, _), Some len, _), Sil.Sizeof (elt2, None, _) | Sil.Sizeof (Typ.Tarray (elt, _), Some len, _), Sil.Sizeof (elt2, None, _)
(* pattern: sizeof(elt[len]) / sizeof(elt) = len *) (* pattern: sizeof(elt[len]) / sizeof(elt) = len *)
when Sil.typ_equal elt elt2 -> when Typ.equal elt elt2 ->
len len
| Sil.Sizeof (Sil.Tarray (elt, Some len), None, _), Sil.Sizeof (elt2, None, _) | Sil.Sizeof (Typ.Tarray (elt, Some len), None, _), Sil.Sizeof (elt2, None, _)
(* pattern: sizeof(elt[len]) / sizeof(elt) = len *) (* pattern: sizeof(elt[len]) / sizeof(elt) = len *)
when Sil.typ_equal elt elt2 -> when Typ.equal elt elt2 ->
Sil.Const (Sil.Cint len) Sil.Const (Sil.Cint len)
| _ -> | _ ->
if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.Div, e1', e2') if abs then Sil.exp_get_undefined false else Sil.BinOp (Sil.Div, e1', e2')
@ -1007,7 +1007,7 @@ let atom_normalize sub a0 =
(* n1-e1 == n2 -> e1==n1-n2 *) (* n1-e1 == n2 -> e1==n1-n2 *)
(e1, Sil.exp_int (n1 -- n2)) (e1, Sil.exp_int (n1 -- n2))
| Sil.Lfield (e1', fld1, _), Sil.Lfield (e2', fld2, _) -> | Sil.Lfield (e1', fld1, _), Sil.Lfield (e2', fld2, _) ->
if Sil.fld_equal fld1 fld2 if Ident.fieldname_equal fld1 fld2
then normalize_eq (e1', e2') then normalize_eq (e1', e2')
else eq else eq
| Sil.Lindex (e1', idx1), Sil.Lindex (e2', idx2) -> | Sil.Lindex (e1', idx1), Sil.Lindex (e2', idx2) ->
@ -1090,14 +1090,14 @@ let rec create_strexp_of_type tenvo struct_init_mode typ len inst =
if !Config.curr_language = Config.Java && inst = Sil.Ialloc if !Config.curr_language = Config.Java && inst = Sil.Ialloc
then then
match typ with match typ with
| Sil.Tfloat _ -> Sil.Const (Sil.Cfloat 0.0) | Typ.Tfloat _ -> Sil.Const (Sil.Cfloat 0.0)
| _ -> Sil.exp_zero | _ -> Sil.exp_zero
else else
create_fresh_var () in create_fresh_var () in
match typ, len with match typ, len with
| (Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _), None -> | (Typ.Tint _ | Typ.Tfloat _ | Typ.Tvoid | Typ.Tfun _ | Typ.Tptr _), None ->
Sil.Eexp (init_value (), inst) Sil.Eexp (init_value (), inst)
| Sil.Tstruct { Sil.instance_fields }, _ -> ( | Typ.Tstruct { Typ.instance_fields }, _ -> (
match struct_init_mode with match struct_init_mode with
| No_init -> | No_init ->
Sil.Estruct ([], inst) Sil.Estruct ([], inst)
@ -1105,22 +1105,22 @@ let rec create_strexp_of_type tenvo struct_init_mode typ len inst =
(* pass len as an accumulator, so that it is passed to create_strexp_of_type for the last (* pass len as an accumulator, so that it is passed to create_strexp_of_type for the last
field, but always return None so that only the last field receives len *) field, but always return None so that only the last field receives len *)
let f (fld, t, a) (flds, len) = let f (fld, t, a) (flds, len) =
if Sil.is_objc_ref_counter_field (fld, t, a) then if Typ.is_objc_ref_counter_field (fld, t, a) then
((fld, Sil.Eexp (Sil.exp_one, inst)) :: flds, None) ((fld, Sil.Eexp (Sil.exp_one, inst)) :: flds, None)
else else
((fld, create_strexp_of_type tenvo struct_init_mode t len inst) :: flds, None) in ((fld, create_strexp_of_type tenvo struct_init_mode t len inst) :: flds, None) in
let flds, _ = IList.fold_right f instance_fields ([], len) in let flds, _ = IList.fold_right f instance_fields ([], len) in
Sil.Estruct (flds, inst) Sil.Estruct (flds, inst)
) )
| Sil.Tarray (_, len_opt), None -> | Typ.Tarray (_, len_opt), None ->
let len = match len_opt with let len = match len_opt with
| None -> Sil.exp_get_undefined false | None -> Sil.exp_get_undefined false
| Some len -> Sil.Const (Sil.Cint len) in | Some len -> Sil.Const (Sil.Cint len) in
Sil.Earray (len, [], inst) Sil.Earray (len, [], inst)
| Sil.Tarray _, Some len -> | Typ.Tarray _, Some len ->
Sil.Earray (len, [], inst) Sil.Earray (len, [], inst)
| Sil.Tvar _, _ | Typ.Tvar _, _
| (Sil.Tint _ | Sil.Tfloat _ | Sil.Tvoid | Sil.Tfun _ | Sil.Tptr _), Some _ -> | (Typ.Tint _ | Typ.Tfloat _ | Typ.Tvoid | Typ.Tfun _ | Typ.Tptr _), Some _ ->
assert false assert false
(** Sil.Construct a pointsto. *) (** Sil.Construct a pointsto. *)
@ -1163,22 +1163,22 @@ let rec hpred_normalize sub hpred =
let normalized_cnt = strexp_normalize sub cnt in let normalized_cnt = strexp_normalize sub cnt in
let normalized_te = texp_normalize sub te in let normalized_te = texp_normalize sub te in
begin match normalized_cnt, normalized_te with begin match normalized_cnt, normalized_te with
| Sil.Earray (Sil.Sizeof _ as size, [], inst), Sil.Sizeof (Sil.Tarray _, _, _) -> | Sil.Earray (Sil.Sizeof _ as size, [], inst), Sil.Sizeof (Typ.Tarray _, _, _) ->
(* check for an empty array whose size expression is (Sizeof type), and turn the array (* check for an empty array whose size expression is (Sizeof type), and turn the array
into a strexp of the given type *) into a strexp of the given type *)
let hpred' = mk_ptsto_exp None Fld_init (root, size, None) inst in let hpred' = mk_ptsto_exp None Fld_init (root, size, None) inst in
replace_hpred hpred' replace_hpred hpred'
| ( Sil.Earray (Sil.BinOp (Sil.Mult, Sil.Sizeof (t, None, st1), x), esel, inst) | ( Sil.Earray (Sil.BinOp (Sil.Mult, Sil.Sizeof (t, None, st1), x), esel, inst)
| Sil.Earray (Sil.BinOp (Sil.Mult, x, Sil.Sizeof (t, None, st1)), esel, inst)), | Sil.Earray (Sil.BinOp (Sil.Mult, x, Sil.Sizeof (t, None, st1)), esel, inst)),
Sil.Sizeof (Sil.Tarray (elt, _) as arr, _, _) Sil.Sizeof (Typ.Tarray (elt, _) as arr, _, _)
when Sil.typ_equal t elt -> when Typ.equal t elt ->
let len = Some x in let len = Some x in
let hpred' = mk_ptsto_exp None Fld_init (root, Sil.Sizeof (arr, len, st1), None) inst in let hpred' = mk_ptsto_exp None Fld_init (root, Sil.Sizeof (arr, len, st1), None) inst in
replace_hpred (replace_array_contents hpred' esel) replace_hpred (replace_array_contents hpred' esel)
| ( Sil.Earray (Sil.BinOp (Sil.Mult, Sil.Sizeof (t, Some len, st1), x), esel, inst) | ( Sil.Earray (Sil.BinOp (Sil.Mult, Sil.Sizeof (t, Some len, st1), x), esel, inst)
| Sil.Earray (Sil.BinOp (Sil.Mult, x, Sil.Sizeof (t, Some len, st1)), esel, inst)), | Sil.Earray (Sil.BinOp (Sil.Mult, x, Sil.Sizeof (t, Some len, st1)), esel, inst)),
Sil.Sizeof (Sil.Tarray (elt, _) as arr, _, _) Sil.Sizeof (Typ.Tarray (elt, _) as arr, _, _)
when Sil.typ_equal t elt -> when Typ.equal t elt ->
let len = Some (Sil.BinOp(Sil.Mult, x, len)) in let len = Some (Sil.BinOp(Sil.Mult, x, len)) in
let hpred' = mk_ptsto_exp None Fld_init (root, Sil.Sizeof (arr, len, st1), None) inst in let hpred' = mk_ptsto_exp None Fld_init (root, Sil.Sizeof (arr, len, st1), None) inst in
replace_hpred (replace_array_contents hpred' esel) replace_hpred (replace_array_contents hpred' esel)
@ -1291,8 +1291,8 @@ let rec pi_sorted_remove_redundant = function
let sigma_get_unsigned_exps sigma = let sigma_get_unsigned_exps sigma =
let uexps = ref [] in let uexps = ref [] in
let do_hpred = function let do_hpred = function
| Sil.Hpointsto (_, Sil.Eexp (e, _), Sil.Sizeof (Sil.Tint ik, _, _)) | Sil.Hpointsto (_, Sil.Eexp (e, _), Sil.Sizeof (Typ.Tint ik, _, _))
when Sil.ikind_is_unsigned ik -> when Typ.ikind_is_unsigned ik ->
uexps := e :: !uexps uexps := e :: !uexps
| _ -> () in | _ -> () in
IList.iter do_hpred sigma; IList.iter do_hpred sigma;
@ -1391,11 +1391,11 @@ let lexp_normalize_prop p lexp =
to ensure the soundness of this collapsing. *) to ensure the soundness of this collapsing. *)
let exp_collapse_consecutive_indices_prop typ exp = let exp_collapse_consecutive_indices_prop typ exp =
let typ_is_base = function let typ_is_base = function
| Sil.Tint _ | Sil.Tfloat _ | Sil.Tstruct _ | Sil.Tvoid | Sil.Tfun _ -> true | Typ.Tint _ | Typ.Tfloat _ | Typ.Tstruct _ | Typ.Tvoid | Typ.Tfun _ -> true
| _ -> false in | _ -> false in
let typ_is_one_step_from_base = let typ_is_one_step_from_base =
match typ with match typ with
| Sil.Tptr (t, _) | Sil.Tarray (t, _) -> typ_is_base t | Typ.Tptr (t, _) | Typ.Tarray (t, _) -> typ_is_base t
| _ -> false in | _ -> false in
let rec exp_remove e0 = let rec exp_remove e0 =
match e0 with match e0 with
@ -1966,7 +1966,7 @@ type arith_problem =
| Div0 of Sil.exp | Div0 of Sil.exp
(* unary minus of unsigned type applied to the given expression *) (* unary minus of unsigned type applied to the given expression *)
| UminusUnsigned of Sil.exp * Sil.typ | UminusUnsigned of Sil.exp * Typ.t
(** Look for an arithmetic problem in [exp] *) (** Look for an arithmetic problem in [exp] *)
let find_arithmetic_problem proc_node_session prop exp = let find_arithmetic_problem proc_node_session prop exp =
@ -1982,8 +1982,8 @@ let find_arithmetic_problem proc_node_session prop exp =
let rec walk = function let rec walk = function
| Sil.Var _ -> () | Sil.Var _ -> ()
| Sil.UnOp (Sil.Neg, e, Some ( | Sil.UnOp (Sil.Neg, e, Some (
(Sil.Tint (Typ.Tint
(Sil.IUChar | Sil.IUInt | Sil.IUShort | Sil.IULong | Sil.IULongLong) as typ))) -> (Typ.IUChar | Typ.IUInt | Typ.IUShort | Typ.IULong | Typ.IULongLong) as typ))) ->
uminus_unsigned := (e, typ) :: !uminus_unsigned uminus_unsigned := (e, typ) :: !uminus_unsigned
| Sil.UnOp(_, e, _) -> walk e | Sil.UnOp(_, e, _) -> walk e
| Sil.BinOp(op, e1, e2) -> | Sil.BinOp(op, e1, e2) ->
@ -2821,7 +2821,7 @@ let find_equal_formal_path e prop =
match strexp with match strexp with
| Sil.Eexp (exp2, _) when Sil.exp_equal exp2 e -> | Sil.Eexp (exp2, _) when Sil.exp_equal exp2 e ->
(match find_in_sigma exp1 seen_hpreds with (match find_in_sigma exp1 seen_hpreds with
| Some exp' -> Some (Sil.Lfield (exp', field, Sil.Tvoid)) | Some exp' -> Some (Sil.Lfield (exp', field, Typ.Tvoid))
| None -> None) | None -> None)
| _ -> None) fields None | _ -> None) fields None
| _ -> None) (get_sigma prop) None in | _ -> None) (get_sigma prop) None in
@ -3008,7 +3008,7 @@ let prop_replace_sub sub p =
{ p with sub = nsub } { p with sub = nsub }
let unstructured_type = function let unstructured_type = function
| Sil.Tstruct _ | Sil.Tarray _ -> false | Typ.Tstruct _ | Typ.Tarray _ -> false
| _ -> true | _ -> true
let rec pp_ren pe f = function let rec pp_ren pe f = function

@ -165,7 +165,7 @@ type arith_problem =
| Div0 of Sil.exp | Div0 of Sil.exp
(* unary minus of unsigned type applied to the given expression *) (* unary minus of unsigned type applied to the given expression *)
| UminusUnsigned of Sil.exp * Sil.typ | UminusUnsigned of Sil.exp * Typ.t
(** Look for an arithmetic problem in [exp] *) (** Look for an arithmetic problem in [exp] *)
val find_arithmetic_problem : path_pos -> normal t -> Sil.exp -> arith_problem option * normal t val find_arithmetic_problem : path_pos -> normal t -> Sil.exp -> arith_problem option * normal t
@ -181,7 +181,7 @@ val exp_normalize_noabs : Sil.subst -> Sil.exp -> Sil.exp
(** Collapse consecutive indices that should be added. For instance, (** Collapse consecutive indices that should be added. For instance,
this function reduces x[1][1] to x[2]. The [typ] argument is used this function reduces x[1][1] to x[2]. The [typ] argument is used
to ensure the soundness of this collapsing. *) to ensure the soundness of this collapsing. *)
val exp_collapse_consecutive_indices_prop : Sil.typ -> Sil.exp -> Sil.exp val exp_collapse_consecutive_indices_prop : Typ.t -> Sil.exp -> Sil.exp
(** Normalize [exp] used for the address of a heap cell. (** Normalize [exp] used for the address of a heap cell.
This normalization does not combine two offsets inside [exp]. *) This normalization does not combine two offsets inside [exp]. *)
@ -222,7 +222,7 @@ val mk_eq : exp -> exp -> atom
(** create a strexp of the given type, populating the structures if [expand_structs] is true *) (** create a strexp of the given type, populating the structures if [expand_structs] is true *)
val create_strexp_of_type : val create_strexp_of_type :
Tenv.t option -> struct_init_mode -> Sil.typ -> Sil.exp option -> Sil.inst -> Sil.strexp Tenv.t option -> struct_init_mode -> Typ.t -> Sil.exp option -> Sil.inst -> Sil.strexp
(** Construct a pointsto. *) (** Construct a pointsto. *)
val mk_ptsto : exp -> strexp -> exp -> hpred val mk_ptsto : exp -> strexp -> exp -> hpred
@ -320,7 +320,7 @@ val add_or_replace_exp_attribute_check_changed : (Sil.attribute -> Sil.attribute
val add_or_replace_exp_attribute : normal t -> exp -> attribute -> normal t val add_or_replace_exp_attribute : normal t -> exp -> attribute -> normal t
(** mark Sil.Var's or Sil.Lvar's as undefined *) (** mark Sil.Var's or Sil.Lvar's as undefined *)
val mark_vars_as_undefined : normal t -> Sil.exp list -> Procname.t -> Sil.item_annotation -> val mark_vars_as_undefined : normal t -> Sil.exp list -> Procname.t -> Typ.item_annotation ->
Location.t -> Sil.path_pos -> normal t Location.t -> Sil.path_pos -> normal t
(** Remove an attribute from all the atoms in the heap *) (** Remove an attribute from all the atoms in the heap *)
@ -501,7 +501,7 @@ val compute_reachable_hpreds : hpred list -> Sil.ExpSet.t -> Sil.HpredSet.t * Si
(** if possible, produce a (fieldname, typ) path from one of the [src_exps] to [snk_exp] using (** if possible, produce a (fieldname, typ) path from one of the [src_exps] to [snk_exp] using
[reachable_hpreds]. *) [reachable_hpreds]. *)
val get_fld_typ_path_opt : Sil.ExpSet.t -> Sil.exp -> Sil.HpredSet.t -> val get_fld_typ_path_opt : Sil.ExpSet.t -> Sil.exp -> Sil.HpredSet.t ->
(Ident.fieldname option * Sil.typ) list option (Ident.fieldname option * Typ.t) list option
(** filter [pi] by removing the pure atoms that do not contain an expression in [exps] *) (** filter [pi] by removing the pure atoms that do not contain an expression in [exps] *)
val compute_reachable_atoms : pi -> Sil.ExpSet.t -> pi val compute_reachable_atoms : pi -> Sil.ExpSet.t -> pi

@ -131,7 +131,7 @@ let rec compute_sexp_diff (se1: Sil.strexp) (se2: Sil.strexp) : Obj.t list = mat
and compute_fsel_diff fsel1 fsel2 : Obj.t list = match fsel1, fsel2 with and compute_fsel_diff fsel1 fsel2 : Obj.t list = match fsel1, fsel2 with
| ((f1, se1):: fsel1'), (((f2, se2) as x):: fsel2') -> | ((f1, se1):: fsel1'), (((f2, se2) as x):: fsel2') ->
(match Sil.fld_compare f1 f2 with (match Ident.fieldname_compare f1 f2 with
| n when n < 0 -> compute_fsel_diff fsel1' fsel2 | n when n < 0 -> compute_fsel_diff fsel1' fsel2
| 0 -> compute_sexp_diff se1 se2 @ compute_fsel_diff fsel1' fsel2' | 0 -> compute_sexp_diff se1 se2 @ compute_fsel_diff fsel1' fsel2'
| _ -> (Obj.repr x) :: compute_fsel_diff fsel1 fsel2') | _ -> (Obj.repr x) :: compute_fsel_diff fsel1 fsel2')

@ -41,8 +41,8 @@ let rec remove_redundancy have_same_key acc = function
else remove_redundancy have_same_key (x:: acc) l else remove_redundancy have_same_key (x:: acc) l
let rec is_java_class = function let rec is_java_class = function
| Sil.Tstruct struct_typ -> Sil.struct_typ_is_java_class struct_typ | Typ.Tstruct struct_typ -> Typ.struct_typ_is_java_class struct_typ
| Sil.Tarray (inner_typ, _) | Tptr (inner_typ, _) -> is_java_class inner_typ | Typ.Tarray (inner_typ, _) | Tptr (inner_typ, _) -> is_java_class inner_typ
| _ -> false | _ -> false
(** {2 Ordinary Theorem Proving} *) (** {2 Ordinary Theorem Proving} *)
@ -164,24 +164,24 @@ end
(** Return true if the two types have sizes which can be compared *) (** Return true if the two types have sizes which can be compared *)
let type_size_comparable t1 t2 = match t1, t2 with let type_size_comparable t1 t2 = match t1, t2 with
| Sil.Tint _, Sil.Tint _ -> true | Typ.Tint _, Typ.Tint _ -> true
| _ -> false | _ -> false
(** Compare the size of comparable types *) (** Compare the size of comparable types *)
let type_size_compare t1 t2 = let type_size_compare t1 t2 =
let ik_compare ik1 ik2 = let ik_compare ik1 ik2 =
let ik_size = function let ik_size = function
| Sil.IChar | Sil.ISChar | Sil.IUChar | Sil.IBool -> 1 | Typ.IChar | Typ.ISChar | Typ.IUChar | Typ.IBool -> 1
| Sil.IShort | Sil.IUShort -> 2 | Typ.IShort | Typ.IUShort -> 2
| Sil.IInt | Sil.IUInt -> 3 | Typ.IInt | Typ.IUInt -> 3
| Sil.ILong | Sil.IULong -> 4 | Typ.ILong | Typ.IULong -> 4
| Sil.ILongLong | Sil.IULongLong -> 5 | Typ.ILongLong | Typ.IULongLong -> 5
| Sil.I128 | Sil.IU128 -> 6 in | Typ.I128 | Typ.IU128 -> 6 in
let n1 = ik_size ik1 in let n1 = ik_size ik1 in
let n2 = ik_size ik2 in let n2 = ik_size ik2 in
n1 - n2 in n1 - n2 in
match t1, t2 with match t1, t2 with
| Sil.Tint ik1, Sil.Tint ik2 -> | Typ.Tint ik1, Typ.Tint ik2 ->
Some (ik_compare ik1 ik2) Some (ik_compare ik1 ik2)
| _ -> None | _ -> None
@ -371,7 +371,7 @@ end = struct
let add_lt_minus1_e e = let add_lt_minus1_e e =
lts := (Sil.exp_minus_one, e)::!lts in lts := (Sil.exp_minus_one, e)::!lts in
let texp_is_unsigned = function let texp_is_unsigned = function
| Sil.Sizeof (Sil.Tint ik, _, _) -> Sil.ikind_is_unsigned ik | Sil.Sizeof (Typ.Tint ik, _, _) -> Typ.ikind_is_unsigned ik
| _ -> false in | _ -> false in
let strexp_lt_minus1 = function let strexp_lt_minus1 = function
| Sil.Eexp (e, _) -> add_lt_minus1_e e | Sil.Eexp (e, _) -> add_lt_minus1_e e
@ -1233,7 +1233,8 @@ let array_len_imply calc_missing subs len1 len2 indices2 =
[se1[sub1]] is an instance of [se2[sub2]]. Raise IMPL_FALSE if not [se1[sub1]] is an instance of [se2[sub2]]. Raise IMPL_FALSE if not
possible. *) possible. *)
let rec sexp_imply source calc_index_frame calc_missing subs se1 se2 typ2 : subst2 * (Sil.strexp option) * (Sil.strexp option) = let rec sexp_imply source calc_index_frame calc_missing subs se1 se2 typ2 : subst2 * (Sil.strexp option) * (Sil.strexp option) =
(* L.d_str "sexp_imply "; Sil.d_sexp se1; L.d_str " "; Sil.d_sexp se2; L.d_str " : "; Sil.d_typ_full typ2; L.d_ln(); *) (* L.d_str "sexp_imply "; Sil.d_sexp se1; L.d_str " "; Sil.d_sexp se2;
L.d_str " : "; Typ.d_full typ2; L.d_ln(); *)
match se1, se2 with match se1, se2 with
| Sil.Eexp (e1, _), Sil.Eexp (e2, _) -> | Sil.Eexp (e1, _), Sil.Eexp (e2, _) ->
(exp_imply calc_missing subs e1 e2, None, None) (exp_imply calc_missing subs e1 e2, None, None)
@ -1280,10 +1281,10 @@ let rec sexp_imply source calc_index_frame calc_missing subs se1 se2 typ2 : subs
sexp_imply source calc_index_frame calc_missing subs se1' se2 typ2 sexp_imply source calc_index_frame calc_missing subs se1' se2 typ2
| Sil.Earray (len, _, _), Sil.Eexp (_, inst) -> | Sil.Earray (len, _, _), Sil.Eexp (_, inst) ->
let se2' = Sil.Earray (len, [(Sil.exp_zero, se2)], inst) in let se2' = Sil.Earray (len, [(Sil.exp_zero, se2)], inst) in
let typ2' = Sil.Tarray (typ2, None) in let typ2' = Typ.Tarray (typ2, None) in
(* In the sexp_imply, struct_imply, array_imply, and sexp_imply_nolhs functions, the typ2 (* In the sexp_imply, struct_imply, array_imply, and sexp_imply_nolhs functions, the typ2
argument is only used by eventually passing its value to Sil.struct_typ_fld, Sil.Lfield, argument is only used by eventually passing its value to Typ.struct_typ_fld, Sil.Lfield,
Sil.struct_typ_fld, or Sil.array_typ_elem. None of these are sensitive to the length field Typ.struct_typ_fld, or Typ.array_elem. None of these are sensitive to the length field
of Tarray, so forgetting the length of typ2' here is not a problem. *) of Tarray, so forgetting the length of typ2' here is not a problem. *)
sexp_imply source true calc_missing subs se1 se2' typ2' (* calculate index_frame because the rhs is a singleton array *) sexp_imply source true calc_missing subs se1 se2' typ2' (* calculate index_frame because the rhs is a singleton array *)
| _ -> | _ ->
@ -1297,7 +1298,7 @@ and struct_imply source calc_missing subs fsel1 fsel2 typ2 : subst2 * ((Ident.fi
begin begin
match Ident.fieldname_compare f1 f2 with match Ident.fieldname_compare f1 f2 with
| 0 -> | 0 ->
let typ' = Sil.struct_typ_fld (Some Sil.Tvoid) f2 typ2 in let typ' = Typ.struct_typ_fld (Some Typ.Tvoid) f2 typ2 in
let subs', se_frame, se_missing = sexp_imply (Sil.Lfield (source, f2, typ2)) false calc_missing subs se1 se2 typ' in let subs', se_frame, se_missing = sexp_imply (Sil.Lfield (source, f2, typ2)) false calc_missing subs se1 se2 typ' in
let subs'', fld_frame, fld_missing = struct_imply source calc_missing subs' fsel1' fsel2' typ2 in let subs'', fld_frame, fld_missing = struct_imply source calc_missing subs' fsel1' fsel2' typ2 in
let fld_frame' = match se_frame with let fld_frame' = match se_frame with
@ -1311,14 +1312,14 @@ and struct_imply source calc_missing subs fsel1 fsel2 typ2 : subst2 * ((Ident.fi
let subs', fld_frame, fld_missing = struct_imply source calc_missing subs fsel1' fsel2 typ2 in let subs', fld_frame, fld_missing = struct_imply source calc_missing subs fsel1' fsel2 typ2 in
subs', ((f1, se1) :: fld_frame), fld_missing subs', ((f1, se1) :: fld_frame), fld_missing
| _ -> | _ ->
let typ' = Sil.struct_typ_fld (Some Sil.Tvoid) f2 typ2 in let typ' = Typ.struct_typ_fld (Some Typ.Tvoid) f2 typ2 in
let subs' = sexp_imply_nolhs (Sil.Lfield (source, f2, typ2)) calc_missing subs se2 typ' in let subs' = sexp_imply_nolhs (Sil.Lfield (source, f2, typ2)) calc_missing subs se2 typ' in
let subs', fld_frame, fld_missing = struct_imply source calc_missing subs' fsel1 fsel2' typ2 in let subs', fld_frame, fld_missing = struct_imply source calc_missing subs' fsel1 fsel2' typ2 in
let fld_missing' = (f2, se2) :: fld_missing in let fld_missing' = (f2, se2) :: fld_missing in
subs', fld_frame, fld_missing' subs', fld_frame, fld_missing'
end end
| [], (f2, se2) :: fsel2' -> | [], (f2, se2) :: fsel2' ->
let typ' = Sil.struct_typ_fld (Some Sil.Tvoid) f2 typ2 in let typ' = Typ.struct_typ_fld (Some Typ.Tvoid) f2 typ2 in
let subs' = sexp_imply_nolhs (Sil.Lfield (source, f2, typ2)) calc_missing subs se2 typ' in let subs' = sexp_imply_nolhs (Sil.Lfield (source, f2, typ2)) calc_missing subs se2 typ' in
let subs'', fld_frame, fld_missing = struct_imply source calc_missing subs' [] fsel2' typ2 in let subs'', fld_frame, fld_missing = struct_imply source calc_missing subs' [] fsel2' typ2 in
subs'', fld_frame, (f2, se2):: fld_missing subs'', fld_frame, (f2, se2):: fld_missing
@ -1326,7 +1327,7 @@ and struct_imply source calc_missing subs fsel1 fsel2 typ2 : subst2 * ((Ident.fi
and array_imply source calc_index_frame calc_missing subs esel1 esel2 typ2 and array_imply source calc_index_frame calc_missing subs esel1 esel2 typ2
: subst2 * ((Sil.exp * Sil.strexp) list) * ((Sil.exp * Sil.strexp) list) : subst2 * ((Sil.exp * Sil.strexp) list) * ((Sil.exp * Sil.strexp) list)
= =
let typ_elem = Sil.array_typ_elem (Some Sil.Tvoid) typ2 in let typ_elem = Typ.array_elem (Some Typ.Tvoid) typ2 in
match esel1, esel2 with match esel1, esel2 with
| _,[] -> subs, esel1, [] | _,[] -> subs, esel1, []
| (e1, se1) :: esel1', (e2, se2) :: esel2' -> | (e1, se1) :: esel1', (e2, se2) :: esel2' ->
@ -1429,19 +1430,19 @@ let expand_hpred_pointer calc_index_frame hpred : bool * bool * Sil.hpred =
let rec expand changed calc_index_frame hpred = match hpred with let rec expand changed calc_index_frame hpred = match hpred with
| Sil.Hpointsto (Sil.Lfield (e, fld, typ_fld), se, t) -> | Sil.Hpointsto (Sil.Lfield (e, fld, typ_fld), se, t) ->
let t' = match t, typ_fld with let t' = match t, typ_fld with
| _, Sil.Tstruct _ -> (* the struct type of fld is known *) | _, Typ.Tstruct _ -> (* the struct type of fld is known *)
Sil.Sizeof (typ_fld, None, Sil.Subtype.exact) Sil.Sizeof (typ_fld, None, Sil.Subtype.exact)
| Sil.Sizeof (t1, len, st), _ -> | Sil.Sizeof (t1, len, st), _ ->
(* the struct type of fld is not known -- typically Tvoid *) (* the struct type of fld is not known -- typically Tvoid *)
Sil.Sizeof Sil.Sizeof
(Sil.Tstruct (Typ.Tstruct
{ Sil.instance_fields = [(fld, t1, Sil.item_annotation_empty)]; { Typ.instance_fields = [(fld, t1, Typ.item_annotation_empty)];
static_fields = []; static_fields = [];
csu = Csu.Struct; csu = Csu.Struct;
struct_name = None; struct_name = None;
Sil.superclasses = []; Typ.superclasses = [];
Sil.def_methods = []; Typ.def_methods = [];
Sil.struct_annotations = Sil.item_annotation_empty; Typ.struct_annotations = Typ.item_annotation_empty;
}, len, st) }, len, st)
(* None as we don't know the stuct name *) (* None as we don't know the stuct name *)
| _ -> raise (Failure "expand_hpred_pointer: Unexpected non-sizeof type in Lfield") in | _ -> raise (Failure "expand_hpred_pointer: Unexpected non-sizeof type in Lfield") in
@ -1449,7 +1450,7 @@ let expand_hpred_pointer calc_index_frame hpred : bool * bool * Sil.hpred =
expand true true hpred' expand true true hpred'
| Sil.Hpointsto (Sil.Lindex (e, ind), se, t) -> | Sil.Hpointsto (Sil.Lindex (e, ind), se, t) ->
let t' = match t with let t' = match t with
| Sil.Sizeof (t_, len, st) -> Sil.Sizeof (Sil.Tarray (t_, None), len, st) | Sil.Sizeof (t_, len, st) -> Sil.Sizeof (Typ.Tarray (t_, None), len, st)
| _ -> raise (Failure "expand_hpred_pointer: Unexpected non-sizeof type in Lindex") in | _ -> raise (Failure "expand_hpred_pointer: Unexpected non-sizeof type in Lindex") in
let len = match t' with let len = match t' with
| Sil.Sizeof (_, Some len, _) -> len | Sil.Sizeof (_, Some len, _) -> len
@ -1476,9 +1477,9 @@ struct
let is_interface tenv class_name = let is_interface tenv class_name =
match Tenv.lookup tenv class_name with match Tenv.lookup tenv class_name with
| Some ({ Sil.csu = Csu.Class Csu.Java; struct_name = Some _ } as struct_typ) -> | Some ({ Typ.csu = Csu.Class Csu.Java; struct_name = Some _ } as struct_typ) ->
(IList.length struct_typ.Sil.instance_fields = 0) && (IList.length struct_typ.Typ.instance_fields = 0) &&
(IList.length struct_typ.Sil.def_methods = 0) (IList.length struct_typ.Typ.def_methods = 0)
| _ -> false | _ -> false
let is_root_class class_name = let is_root_class class_name =
@ -1494,7 +1495,7 @@ struct
let rec check cn = let rec check cn =
Typename.equal cn c2 || is_root_class c2 || Typename.equal cn c2 || is_root_class c2 ||
match Tenv.lookup tenv cn with match Tenv.lookup tenv cn with
| Some ({ Sil.struct_name = Some _; csu = Csu.Class _; superclasses }) -> | Some ({ Typ.struct_name = Some _; csu = Csu.Class _; superclasses }) ->
IList.exists check superclasses IList.exists check superclasses
| _ -> false in | _ -> false in
check c1 check c1
@ -1506,28 +1507,28 @@ struct
(** check that t1 and t2 are the same primitive type *) (** check that t1 and t2 are the same primitive type *)
let check_subtype_basic_type t1 t2 = let check_subtype_basic_type t1 t2 =
match t2 with match t2 with
| Sil.Tint Sil.IInt | Sil.Tint Sil.IBool | Typ.Tint Typ.IInt | Typ.Tint Typ.IBool
| Sil.Tint Sil.IChar | Sil.Tfloat Sil.FDouble | Typ.Tint Typ.IChar | Typ.Tfloat Typ.FDouble
| Sil.Tfloat Sil.FFloat | Sil.Tint Sil.ILong | Typ.Tfloat Typ.FFloat | Typ.Tint Typ.ILong
| Sil.Tint Sil.IShort -> Sil.typ_equal t1 t2 | Typ.Tint Typ.IShort -> Typ.equal t1 t2
| _ -> false | _ -> false
(** check if t1 is a subtype of t2, in Java *) (** check if t1 is a subtype of t2, in Java *)
let rec check_subtype_java tenv t1 t2 = let rec check_subtype_java tenv t1 t2 =
match t1, t2 with match t1, t2 with
| Sil.Tstruct { Sil.csu = Csu.Class Csu.Java; struct_name = Some c1 }, | Typ.Tstruct { Typ.csu = Csu.Class Csu.Java; struct_name = Some c1 },
Sil.Tstruct { Sil.csu = Csu.Class Csu.Java; struct_name = Some c2 } -> Typ.Tstruct { Typ.csu = Csu.Class Csu.Java; struct_name = Some c2 } ->
let cn1 = Typename.TN_csu (Csu.Class Csu.Java, c1) let cn1 = Typename.TN_csu (Csu.Class Csu.Java, c1)
and cn2 = Typename.TN_csu (Csu.Class Csu.Java, c2) in and cn2 = Typename.TN_csu (Csu.Class Csu.Java, c2) in
check_subclass tenv cn1 cn2 check_subclass tenv cn1 cn2
| Sil.Tarray (dom_type1, _), Sil.Tarray (dom_type2, _) -> | Typ.Tarray (dom_type1, _), Typ.Tarray (dom_type2, _) ->
check_subtype_java tenv dom_type1 dom_type2 check_subtype_java tenv dom_type1 dom_type2
| Sil.Tptr (dom_type1, _), Sil.Tptr (dom_type2, _) -> | Typ.Tptr (dom_type1, _), Typ.Tptr (dom_type2, _) ->
check_subtype_java tenv dom_type1 dom_type2 check_subtype_java tenv dom_type1 dom_type2
| Sil.Tarray _, Sil.Tstruct { Sil.csu = Csu.Class Csu.Java; struct_name = Some c2 } -> | Typ.Tarray _, Typ.Tstruct { Typ.csu = Csu.Class Csu.Java; struct_name = Some c2 } ->
let cn2 = Typename.TN_csu (Csu.Class Csu.Java, c2) in let cn2 = Typename.TN_csu (Csu.Class Csu.Java, c2) in
Typename.equal cn2 serializable_type Typename.equal cn2 serializable_type
|| Typename.equal cn2 cloneable_type || Typename.equal cn2 cloneable_type
@ -1536,7 +1537,7 @@ struct
let get_cpp_objc_type_name t = let get_cpp_objc_type_name t =
match t with match t with
| Sil.Tstruct { Sil.csu = Csu.Class csu; struct_name = Some c } | Typ.Tstruct { Typ.csu = Csu.Class csu; struct_name = Some c }
when csu = Csu.CPP || csu = Csu.Objc -> when csu = Csu.CPP || csu = Csu.Objc ->
Some (Typename.TN_csu (Csu.Class csu, c)) Some (Typename.TN_csu (Csu.Class csu, c))
| _ -> None | _ -> None
@ -1553,20 +1554,20 @@ struct
let rec case_analysis_type_java tenv (t1, st1) (t2, st2) = let rec case_analysis_type_java tenv (t1, st1) (t2, st2) =
match t1, t2 with match t1, t2 with
| Sil.Tstruct { Sil.csu = Csu.Class Csu.Java; struct_name = Some c1 }, | Typ.Tstruct { Typ.csu = Csu.Class Csu.Java; struct_name = Some c1 },
Sil.Tstruct { Sil.csu = Csu.Class Csu.Java; struct_name = Some c2 } -> Typ.Tstruct { Typ.csu = Csu.Class Csu.Java; struct_name = Some c2 } ->
let cn1 = Typename.TN_csu (Csu.Class Csu.Java, c1) let cn1 = Typename.TN_csu (Csu.Class Csu.Java, c1)
and cn2 = Typename.TN_csu (Csu.Class Csu.Java, c2) in and cn2 = Typename.TN_csu (Csu.Class Csu.Java, c2) in
Sil.Subtype.case_analysis (cn1, st1) (cn2, st2) Sil.Subtype.case_analysis (cn1, st1) (cn2, st2)
(check_subclass tenv) (is_interface tenv) (check_subclass tenv) (is_interface tenv)
| Sil.Tarray (dom_type1, _), Sil.Tarray (dom_type2, _) -> | Typ.Tarray (dom_type1, _), Typ.Tarray (dom_type2, _) ->
case_analysis_type_java tenv (dom_type1, st1) (dom_type2, st2) case_analysis_type_java tenv (dom_type1, st1) (dom_type2, st2)
| Sil.Tptr (dom_type1, _), Sil.Tptr (dom_type2, _) -> | Typ.Tptr (dom_type1, _), Typ.Tptr (dom_type2, _) ->
case_analysis_type_java tenv (dom_type1, st1) (dom_type2, st2) case_analysis_type_java tenv (dom_type1, st1) (dom_type2, st2)
| Sil.Tstruct { Sil.csu = Csu.Class Csu.Java; struct_name = Some c1 }, Sil.Tarray _ -> | Typ.Tstruct { Typ.csu = Csu.Class Csu.Java; struct_name = Some c1 }, Typ.Tarray _ ->
let cn1 = Typename.TN_csu (Csu.Class Csu.Java, c1) in let cn1 = Typename.TN_csu (Csu.Class Csu.Java, c1) in
if (Typename.equal cn1 serializable_type if (Typename.equal cn1 serializable_type
|| Typename.equal cn1 cloneable_type || Typename.equal cn1 cloneable_type
@ -1628,13 +1629,13 @@ let cast_exception tenv texp1 texp2 e1 subs =
Note: [pname] wil never be included in the returned result *) Note: [pname] wil never be included in the returned result *)
let get_overrides_of tenv supertype pname = let get_overrides_of tenv supertype pname =
let typ_has_method pname = function let typ_has_method pname = function
| Sil.Tstruct { Sil.def_methods } -> | Typ.Tstruct { Typ.def_methods } ->
IList.exists (fun m -> Procname.equal pname m) def_methods IList.exists (fun m -> Procname.equal pname m) def_methods
| _ -> false in | _ -> false in
let gather_overrides tname struct_typ overrides_acc = let gather_overrides tname struct_typ overrides_acc =
let typ = Sil.Tstruct struct_typ in let typ = Typ.Tstruct struct_typ in
(* get all types in the type environment that are non-reflexive subtypes of [supertype] *) (* get all types in the type environment that are non-reflexive subtypes of [supertype] *)
if not (Sil.typ_equal typ supertype) && Subtyping_check.check_subtype tenv typ supertype then if not (Typ.equal typ supertype) && Subtyping_check.check_subtype tenv typ supertype then
(* only select the ones that implement [pname] as overrides *) (* only select the ones that implement [pname] as overrides *)
let resolved_pname = let resolved_pname =
Procname.replace_class pname (Typename.name tname) in Procname.replace_class pname (Typename.name tname) in
@ -1646,7 +1647,7 @@ let get_overrides_of tenv supertype pname =
(** Check the equality of two types ignoring flags in the subtyping components *) (** Check the equality of two types ignoring flags in the subtyping components *)
let texp_equal_modulo_subtype_flag texp1 texp2 = match texp1, texp2 with let texp_equal_modulo_subtype_flag texp1 texp2 = match texp1, texp2 with
| Sil.Sizeof (t1, len1, st1), Sil.Sizeof (t2, len2, st2) -> | Sil.Sizeof (t1, len1, st1), Sil.Sizeof (t2, len2, st2) ->
Sil.typ_equal t1 t2 Typ.equal t1 t2
&& (opt_equal Sil.exp_equal len1 len2) && (opt_equal Sil.exp_equal len1 len2)
&& Sil.Subtype.equal_modulo_flag st1 st2 && Sil.Subtype.equal_modulo_flag st1 st2
| _ -> Sil.exp_equal texp1 texp2 | _ -> Sil.exp_equal texp1 texp2
@ -1657,15 +1658,15 @@ let texp_imply tenv subs texp1 texp2 e1 calc_missing =
(* classes and arrays in Java, and just classes in C++ and ObjC *) (* classes and arrays in Java, and just classes in C++ and ObjC *)
let types_subject_to_dynamic_cast = let types_subject_to_dynamic_cast =
match texp1, texp2 with match texp1, texp2 with
| Sil.Sizeof ((Sil.Tstruct _) as typ1, _, _), Sil.Sizeof (Sil.Tstruct _, _, _) | Sil.Sizeof ((Typ.Tstruct _) as typ1, _, _), Sil.Sizeof (Typ.Tstruct _, _, _)
| Sil.Sizeof ((Sil.Tarray _) as typ1, _, _), Sil.Sizeof (Sil.Tarray _, _, _) | Sil.Sizeof ((Typ.Tarray _) as typ1, _, _), Sil.Sizeof (Typ.Tarray _, _, _)
| Sil.Sizeof ((Sil.Tarray _) as typ1, _, _), Sil.Sizeof (Sil.Tstruct _, _, _) | Sil.Sizeof ((Typ.Tarray _) as typ1, _, _), Sil.Sizeof (Typ.Tstruct _, _, _)
| Sil.Sizeof ((Sil.Tstruct _) as typ1, _, _), Sil.Sizeof (Sil.Tarray _, _, _) | Sil.Sizeof ((Typ.Tstruct _) as typ1, _, _), Sil.Sizeof (Typ.Tarray _, _, _)
when is_java_class typ1 -> true when is_java_class typ1 -> true
| Sil.Sizeof (typ1, _, _), Sil.Sizeof (typ2, _, _) -> | Sil.Sizeof (typ1, _, _), Sil.Sizeof (typ2, _, _) ->
(Sil.is_cpp_class typ1 && Sil.is_cpp_class typ2) || (Typ.is_cpp_class typ1 && Typ.is_cpp_class typ2) ||
(Sil.is_objc_class typ1 && Sil.is_objc_class typ2) (Typ.is_objc_class typ1 && Typ.is_objc_class typ2)
| _ -> false in | _ -> false in
if types_subject_to_dynamic_cast then if types_subject_to_dynamic_cast then
begin begin
@ -1723,14 +1724,14 @@ let handle_parameter_subtype tenv prop1 sigma2 subs (e1, se1, texp1) (se2, texp2
| _ -> false in | _ -> false in
if IList.exists filter sigma2 then !sub_opt else None in if IList.exists filter sigma2 then !sub_opt else None in
let add_subtype () = match texp1, texp2, se1, se2 with let add_subtype () = match texp1, texp2, se1, se2 with
| Sil.Sizeof (Sil.Tptr (t1_, _), None, _), Sil.Sizeof (Sil.Tptr (t2_, _), None, _), | Sil.Sizeof (Typ.Tptr (t1_, _), None, _), Sil.Sizeof (Typ.Tptr (t2_, _), None, _),
Sil.Eexp (e1', _), Sil.Eexp (e2', _) Sil.Eexp (e1', _), Sil.Eexp (e2', _)
when not (is_allocated_lhs e1') -> when not (is_allocated_lhs e1') ->
begin begin
let t1, t2 = Tenv.expand_type tenv t1_, Tenv.expand_type tenv t2_ in let t1, t2 = Tenv.expand_type tenv t1_, Tenv.expand_type tenv t2_ in
match type_rhs e2' with match type_rhs e2' with
| Some (t2_ptsto, len2, sub2) -> | Some (t2_ptsto, len2, sub2) ->
if not (Sil.typ_equal t1 t2) && Subtyping_check.check_subtype tenv t1 t2 if not (Typ.equal t1 t2) && Subtyping_check.check_subtype tenv t1 t2
then begin then begin
let pos_type_opt, _ = let pos_type_opt, _ =
Subtyping_check.subtype_case_analysis tenv Subtyping_check.subtype_case_analysis tenv
@ -1765,7 +1766,7 @@ let rec hpred_imply tenv calc_index_frame calc_missing subs prop1 sigma2 hpred2
(match Prop.prop_iter_current iter1' with (match Prop.prop_iter_current iter1' with
| Sil.Hpointsto (e1, se1, texp1), _ -> | Sil.Hpointsto (e1, se1, texp1), _ ->
(try (try
let typ2 = Sil.texp_to_typ (Some Sil.Tvoid) texp2 in let typ2 = Sil.texp_to_typ (Some Typ.Tvoid) texp2 in
let typing_frame, typing_missing = texp_imply tenv subs texp1 texp2 e1 calc_missing in let typing_frame, typing_missing = texp_imply tenv subs texp1 texp2 e1 calc_missing in
let se1' = sexp_imply_preprocess se1 texp1 se2 in let se1' = sexp_imply_preprocess se1 texp1 se2 in
let subs', fld_frame, fld_missing = sexp_imply e1 calc_index_frame calc_missing subs se1' se2 typ2 in let subs', fld_frame, fld_missing = sexp_imply e1 calc_index_frame calc_missing subs se1' se2 typ2 in
@ -1966,14 +1967,14 @@ and sigma_imply tenv calc_index_frame calc_missing subs prop1 sigma2 : (subst2 *
let const_string_texp = let const_string_texp =
match !Config.curr_language with match !Config.curr_language with
| Config.Clang -> | Config.Clang ->
Sil.Sizeof (Sil.Tarray (Sil.Tint Sil.IChar, Some len), None, Sil.Subtype.exact) Sil.Sizeof (Typ.Tarray (Typ.Tint Typ.IChar, Some len), None, Sil.Subtype.exact)
| Config.Java -> | Config.Java ->
let object_type = let object_type =
Typename.TN_csu (Csu.Class Csu.Java, Mangled.from_string "java.lang.String") in Typename.TN_csu (Csu.Class Csu.Java, Mangled.from_string "java.lang.String") in
let typ = match Tenv.lookup tenv object_type with let typ = match Tenv.lookup tenv object_type with
| Some typ -> typ | Some typ -> typ
| None -> assert false in | None -> assert false in
Sil.Sizeof (Sil.Tstruct typ, None, Sil.Subtype.exact) in Sil.Sizeof (Typ.Tstruct typ, None, Sil.Subtype.exact) in
Sil.Hpointsto (root, sexp, const_string_texp) in Sil.Hpointsto (root, sexp, const_string_texp) in
let mk_constant_class_hpred s = (* creat an hpred from a constant class *) let mk_constant_class_hpred s = (* creat an hpred from a constant class *)
let root = Sil.Const (Sil.Cclass (Ident.string_to_name s)) in let root = Sil.Const (Sil.Cclass (Ident.string_to_name s)) in
@ -1985,7 +1986,7 @@ and sigma_imply tenv calc_index_frame calc_missing subs prop1 sigma2 : (subst2 *
let typ = match Tenv.lookup tenv class_type with let typ = match Tenv.lookup tenv class_type with
| Some typ -> typ | Some typ -> typ
| None -> assert false in | None -> assert false in
Sil.Sizeof (Sil.Tstruct typ, None, Sil.Subtype.exact) in Sil.Sizeof (Typ.Tstruct typ, None, Sil.Subtype.exact) in
Sil.Hpointsto (root, sexp, class_texp) in Sil.Hpointsto (root, sexp, class_texp) in
try try
(match move_primed_lhs_from_front subs sigma2 with (match move_primed_lhs_from_front subs sigma2 with
@ -2019,7 +2020,7 @@ and sigma_imply tenv calc_index_frame calc_missing subs prop1 sigma2 : (subst2 *
| None -> | None ->
let subs' = match hpred2' with let subs' = match hpred2' with
| Sil.Hpointsto (e2, se2, te2) -> | Sil.Hpointsto (e2, se2, te2) ->
let typ2 = Sil.texp_to_typ (Some Sil.Tvoid) te2 in let typ2 = Sil.texp_to_typ (Some Typ.Tvoid) te2 in
sexp_imply_nolhs e2 calc_missing subs se2 typ2 sexp_imply_nolhs e2 calc_missing subs se2 typ2
| _ -> subs in | _ -> subs in
ProverState.add_missing_sigma [hpred2']; ProverState.add_missing_sigma [hpred2'];

@ -28,13 +28,13 @@ val check_disequal : Prop.normal Prop.t -> exp -> exp -> bool
val check_le : Prop.normal Prop.t -> exp -> exp -> bool val check_le : Prop.normal Prop.t -> exp -> exp -> bool
(** Return true if the two types have sizes which can be compared *) (** Return true if the two types have sizes which can be compared *)
val type_size_comparable : Sil.typ -> Sil.typ -> bool val type_size_comparable : Typ.t -> Typ.t -> bool
(** Check <= on the size of comparable types *) (** Check <= on the size of comparable types *)
val check_type_size_leq : Sil.typ -> Sil.typ -> bool val check_type_size_leq : Typ.t -> Typ.t -> bool
(** Check < on the size of comparable types *) (** Check < on the size of comparable types *)
val check_type_size_lt : Sil.typ -> Sil.typ -> bool val check_type_size_lt : Typ.t -> Typ.t -> bool
(** Check whether [prop |- a]. Result [false] means "don't know". *) (** Check whether [prop |- a]. Result [false] means "don't know". *)
val check_atom : Prop.normal Prop.t -> atom -> bool val check_atom : Prop.normal Prop.t -> atom -> bool
@ -99,7 +99,7 @@ module Subtyping_check :
sig sig
(** check_subtype t1 t2 checks whether t1 is a subtype of t2, given the type environment tenv. *) (** check_subtype t1 t2 checks whether t1 is a subtype of t2, given the type environment tenv. *)
val check_subtype : Tenv.t -> Sil.typ -> Sil.typ -> bool val check_subtype : Tenv.t -> Typ.t -> Typ.t -> bool
(** subtype_case_analysis tenv tecp1 texp2 performs case analysis on [texp1 <: texp2], (** subtype_case_analysis tenv tecp1 texp2 performs case analysis on [texp1 <: texp2],
and returns the updated types in the true and false case, if they are possible *) and returns the updated types in the true and false case, if they are possible *)
@ -107,7 +107,7 @@ sig
end end
val get_overrides_of : Tenv.t -> Sil.typ -> Procname.t -> (typ * Procname.t) list val get_overrides_of : Tenv.t -> Typ.t -> Procname.t -> (Typ.t * Procname.t) list

@ -85,12 +85,12 @@ let bounds_check pname prop len e =
check_bad_index pname prop len e check_bad_index pname prop len e
let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp t let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp t
(off: Sil.offset list) inst : Sil.atom list * Sil.strexp * Sil.typ = (off: Sil.offset list) inst : Sil.atom list * Sil.strexp * Typ.t =
if Config.trace_rearrange then if Config.trace_rearrange then
begin begin
L.d_increase_indent 1; L.d_increase_indent 1;
L.d_strln "entering create_struct_values"; L.d_strln "entering create_struct_values";
L.d_str "typ: "; Sil.d_typ_full t; L.d_ln (); L.d_str "typ: "; Typ.d_full t; L.d_ln ();
L.d_str "off: "; Sil.d_offset_list off; L.d_ln (); L.d_ln () L.d_str "off: "; Sil.d_offset_list off; L.d_ln (); L.d_ln ()
end; end;
let new_id () = let new_id () =
@ -98,9 +98,9 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
Ident.create kind !max_stamp in Ident.create kind !max_stamp in
let res = let res =
match t, off with match t, off with
| Sil.Tstruct _, [] -> | Typ.Tstruct _, [] ->
([], Sil.Estruct ([], inst), t) ([], Sil.Estruct ([], inst), t)
| Sil.Tstruct ({ Sil.instance_fields; static_fields } as struct_typ ), | Typ.Tstruct ({ Typ.instance_fields; static_fields } as struct_typ ),
(Sil.Off_fld (f, _)):: off' -> (Sil.Off_fld (f, _)):: off' ->
let _, t', _ = let _, t', _ =
try try
@ -115,18 +115,18 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
let replace_typ_of_f (f', t', a') = let replace_typ_of_f (f', t', a') =
if Ident.fieldname_equal f f' then (f, res_t', a') else (f', t', a') in if Ident.fieldname_equal f f' then (f, res_t', a') else (f', t', a') in
let instance_fields' = let instance_fields' =
IList.sort Sil.fld_typ_ann_compare (IList.map replace_typ_of_f instance_fields) in IList.sort Typ.fld_typ_ann_compare (IList.map replace_typ_of_f instance_fields) in
(atoms', se, Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields'}) (atoms', se, Typ.Tstruct { struct_typ with Typ.instance_fields = instance_fields'})
| Sil.Tstruct _, (Sil.Off_index e):: off' -> | Typ.Tstruct _, (Sil.Off_index e):: off' ->
let atoms', se', res_t' = let atoms', se', res_t' =
create_struct_values create_struct_values
pname tenv orig_prop footprint_part kind max_stamp t off' inst in pname tenv orig_prop footprint_part kind max_stamp t off' inst in
let e' = Sil.array_clean_new_index footprint_part e in let e' = Sil.array_clean_new_index footprint_part e in
let len = Sil.Var (new_id ()) in let len = Sil.Var (new_id ()) in
let se = Sil.Earray (len, [(e', se')], inst) in let se = Sil.Earray (len, [(e', se')], inst) in
let res_t = Sil.Tarray (res_t', None) in let res_t = Typ.Tarray (res_t', None) in
(Sil.Aeq(e, e') :: atoms', se, res_t) (Sil.Aeq(e, e') :: atoms', se, res_t)
| Sil.Tarray (t', len_), off -> | Typ.Tarray (t', len_), off ->
let len = match len_ with let len = match len_ with
| None -> Sil.Var (new_id ()) | None -> Sil.Var (new_id ())
| Some len -> Sil.Const (Sil.Cint len) in | Some len -> Sil.Const (Sil.Cint len) in
@ -140,20 +140,20 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
pname tenv orig_prop footprint_part kind max_stamp t' off' inst in pname tenv orig_prop footprint_part kind max_stamp t' off' inst in
let e' = Sil.array_clean_new_index footprint_part e in let e' = Sil.array_clean_new_index footprint_part e in
let se = Sil.Earray (len, [(e', se')], inst) in let se = Sil.Earray (len, [(e', se')], inst) in
let res_t = Sil.Tarray (res_t', len_) in let res_t = Typ.Tarray (res_t', len_) in
(Sil.Aeq(e, e') :: atoms', se, res_t) (Sil.Aeq(e, e') :: atoms', se, res_t)
| (Sil.Off_fld _) :: _ -> | (Sil.Off_fld _) :: _ ->
assert false assert false
) )
| Sil.Tint _, [] | Sil.Tfloat _, [] | Sil.Tvoid, [] | Sil.Tfun _, [] | Sil.Tptr _, [] -> | Typ.Tint _, [] | Typ.Tfloat _, [] | Typ.Tvoid, [] | Typ.Tfun _, [] | Typ.Tptr _, [] ->
let id = new_id () in let id = new_id () in
([], Sil.Eexp (Sil.Var id, inst), t) ([], Sil.Eexp (Sil.Var id, inst), t)
| Sil.Tint _, [Sil.Off_index e] | Sil.Tfloat _, [Sil.Off_index e] | Typ.Tint _, [Sil.Off_index e] | Typ.Tfloat _, [Sil.Off_index e]
| Sil.Tvoid, [Sil.Off_index e] | Typ.Tvoid, [Sil.Off_index e]
| Sil.Tfun _, [Sil.Off_index e] | Sil.Tptr _, [Sil.Off_index e] -> | Typ.Tfun _, [Sil.Off_index e] | Typ.Tptr _, [Sil.Off_index e] ->
(* In this case, we lift t to the t array. *) (* In this case, we lift t to the t array. *)
let t' = match t with let t' = match t with
| Sil.Tptr(t', _) -> t' | Typ.Tptr(t', _) -> t'
| _ -> t in | _ -> t in
let len = Sil.Var (new_id ()) in let len = Sil.Var (new_id ()) in
let atoms', se', res_t' = let atoms', se', res_t' =
@ -161,14 +161,16 @@ let rec create_struct_values pname tenv orig_prop footprint_part kind max_stamp
pname tenv orig_prop footprint_part kind max_stamp t' [] inst in pname tenv orig_prop footprint_part kind max_stamp t' [] inst in
let e' = Sil.array_clean_new_index footprint_part e in let e' = Sil.array_clean_new_index footprint_part e in
let se = Sil.Earray (len, [(e', se')], inst) in let se = Sil.Earray (len, [(e', se')], inst) in
let res_t = Sil.Tarray (res_t', None) in let res_t = Typ.Tarray (res_t', None) in
(Sil.Aeq(e, e'):: atoms', se, res_t) (Sil.Aeq(e, e'):: atoms', se, res_t)
| Sil.Tint _, _ | Sil.Tfloat _, _ | Sil.Tvoid, _ | Sil.Tfun _, _ | Sil.Tptr _, _ -> | Typ.Tint _, _ | Typ.Tfloat _, _ | Typ.Tvoid, _ | Typ.Tfun _, _ | Typ.Tptr _, _ ->
L.d_str "create_struct_values type:"; Sil.d_typ_full t; L.d_str " off: "; Sil.d_offset_list off; L.d_ln(); L.d_str "create_struct_values type:"; Typ.d_full t;
L.d_str " off: "; Sil.d_offset_list off; L.d_ln();
raise (Exceptions.Bad_footprint __POS__) raise (Exceptions.Bad_footprint __POS__)
| Sil.Tvar _, _ -> | Typ.Tvar _, _ ->
L.d_str "create_struct_values type:"; Sil.d_typ_full t; L.d_str " off: "; Sil.d_offset_list off; L.d_ln(); L.d_str "create_struct_values type:"; Typ.d_full t;
L.d_str " off: "; Sil.d_offset_list off; L.d_ln();
assert false in assert false in
if Config.trace_rearrange then if Config.trace_rearrange then
@ -200,12 +202,12 @@ let rec _strexp_extend_values
let off_new = Sil.Off_index(Sil.exp_zero):: off in let off_new = Sil.Off_index(Sil.exp_zero):: off in
_strexp_extend_values _strexp_extend_values
pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
| (Sil.Off_fld _) :: _, Sil.Earray _, Sil.Tarray _ -> | (Sil.Off_fld _) :: _, Sil.Earray _, Typ.Tarray _ ->
let off_new = Sil.Off_index(Sil.exp_zero):: off in let off_new = Sil.Off_index(Sil.exp_zero):: off in
_strexp_extend_values _strexp_extend_values
pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst pname tenv orig_prop footprint_part kind max_stamp se typ off_new inst
| (Sil.Off_fld (f, _)):: off', Sil.Estruct (fsel, inst'), | (Sil.Off_fld (f, _)):: off', Sil.Estruct (fsel, inst'),
Sil.Tstruct ({ Sil.instance_fields; static_fields } as struct_typ) -> Typ.Tstruct ({ Typ.instance_fields; static_fields } as struct_typ) ->
let replace_fv new_v fv = if Ident.fieldname_equal (fst fv) f then (f, new_v) else fv in let replace_fv new_v fv = if Ident.fieldname_equal (fst fv) f then (f, new_v) else fv in
let _, typ', _ = let _, typ', _ =
try try
@ -224,9 +226,9 @@ let rec _strexp_extend_values
let res_fsel' = IList.sort Sil.fld_strexp_compare (IList.map replace_fse fsel) in let res_fsel' = IList.sort Sil.fld_strexp_compare (IList.map replace_fse fsel) in
let replace_fta (f, t, a) = let f', t' = replace_fv res_typ' (f, t) in (f', t', a) in let replace_fta (f, t, a) = let f', t' = replace_fv res_typ' (f, t) in (f', t', a) in
let instance_fields' = let instance_fields' =
IList.sort Sil.fld_typ_ann_compare (IList.map replace_fta instance_fields) in IList.sort Typ.fld_typ_ann_compare (IList.map replace_fta instance_fields) in
let struct_typ = let struct_typ =
Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields' } in Typ.Tstruct { struct_typ with Typ.instance_fields = instance_fields' } in
(res_atoms', Sil.Estruct (res_fsel', inst'), struct_typ) :: acc in (res_atoms', Sil.Estruct (res_fsel', inst'), struct_typ) :: acc in
IList.fold_left replace [] atoms_se_typ_list' IList.fold_left replace [] atoms_se_typ_list'
with Not_found -> with Not_found ->
@ -236,19 +238,19 @@ let rec _strexp_extend_values
let res_fsel' = IList.sort Sil.fld_strexp_compare ((f, se'):: fsel) in let res_fsel' = IList.sort Sil.fld_strexp_compare ((f, se'):: fsel) in
let replace_fta (f', t', a') = if Ident.fieldname_equal f' f then (f, res_typ', a') else (f', t', a') in let replace_fta (f', t', a') = if Ident.fieldname_equal f' f then (f, res_typ', a') else (f', t', a') in
let instance_fields' = let instance_fields' =
IList.sort Sil.fld_typ_ann_compare (IList.map replace_fta instance_fields) in IList.sort Typ.fld_typ_ann_compare (IList.map replace_fta instance_fields) in
let struct_typ = Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields' } in let struct_typ = Typ.Tstruct { struct_typ with Typ.instance_fields = instance_fields' } in
[(atoms', Sil.Estruct (res_fsel', inst'), struct_typ)] [(atoms', Sil.Estruct (res_fsel', inst'), struct_typ)]
end end
| (Sil.Off_fld (_, _)):: _, _, _ -> | (Sil.Off_fld (_, _)):: _, _, _ ->
raise (Exceptions.Bad_footprint __POS__) raise (Exceptions.Bad_footprint __POS__)
| (Sil.Off_index _):: _, Sil.Eexp _, Sil.Tint _ | (Sil.Off_index _):: _, Sil.Eexp _, Typ.Tint _
| (Sil.Off_index _):: _, Sil.Eexp _, Sil.Tfloat _ | (Sil.Off_index _):: _, Sil.Eexp _, Typ.Tfloat _
| (Sil.Off_index _):: _, Sil.Eexp _, Sil.Tvoid | (Sil.Off_index _):: _, Sil.Eexp _, Typ.Tvoid
| (Sil.Off_index _):: _, Sil.Eexp _, Sil.Tfun _ | (Sil.Off_index _):: _, Sil.Eexp _, Typ.Tfun _
| (Sil.Off_index _):: _, Sil.Eexp _, Sil.Tptr _ | (Sil.Off_index _):: _, Sil.Eexp _, Typ.Tptr _
| (Sil.Off_index _):: _, Sil.Estruct _, Sil.Tstruct _ -> | (Sil.Off_index _):: _, Sil.Estruct _, Typ.Tstruct _ ->
(* L.d_strln_color Orange "turn into an array"; *) (* L.d_strln_color Orange "turn into an array"; *)
let len = match se with let len = match se with
| Sil.Eexp (_, Sil.Ialloc) -> Sil.exp_one (* if allocated explicitly, we know len is 1 *) | Sil.Eexp (_, Sil.Ialloc) -> Sil.exp_one (* if allocated explicitly, we know len is 1 *)
@ -256,10 +258,10 @@ let rec _strexp_extend_values
if Config.type_size then Sil.exp_one (* Sil.Sizeof (typ, Sil.Subtype.exact) *) if Config.type_size then Sil.exp_one (* Sil.Sizeof (typ, Sil.Subtype.exact) *)
else Sil.Var (new_id ()) in else Sil.Var (new_id ()) in
let se_new = Sil.Earray (len, [(Sil.exp_zero, se)], inst) in let se_new = Sil.Earray (len, [(Sil.exp_zero, se)], inst) in
let typ_new = Sil.Tarray (typ, None) in let typ_new = Typ.Tarray (typ, None) in
_strexp_extend_values _strexp_extend_values
pname tenv orig_prop footprint_part kind max_stamp se_new typ_new off inst pname tenv orig_prop footprint_part kind max_stamp se_new typ_new off inst
| (Sil.Off_index e) :: off', Sil.Earray (len, esel, inst_arr), Sil.Tarray (typ', len_for_typ') -> | (Sil.Off_index e) :: off', Sil.Earray (len, esel, inst_arr), Typ.Tarray (typ', len_for_typ') ->
bounds_check pname orig_prop len e (State.get_loc ()); bounds_check pname orig_prop len e (State.get_loc ());
begin begin
try try
@ -270,10 +272,10 @@ let rec _strexp_extend_values
let replace acc (res_atoms', res_se', res_typ') = let replace acc (res_atoms', res_se', res_typ') =
let replace_ise ise = if Sil.exp_equal e (fst ise) then (e, res_se') else ise in let replace_ise ise = if Sil.exp_equal e (fst ise) then (e, res_se') else ise in
let res_esel' = IList.map replace_ise esel in let res_esel' = IList.map replace_ise esel in
if (Sil.typ_equal res_typ' typ') || (IList.length res_esel' = 1) then if (Typ.equal res_typ' typ') || (IList.length res_esel' = 1) then
( res_atoms' ( res_atoms'
, Sil.Earray (len, res_esel', inst_arr) , Sil.Earray (len, res_esel', inst_arr)
, Sil.Tarray (res_typ', len_for_typ') ) , Typ.Tarray (res_typ', len_for_typ') )
:: acc :: acc
else else
raise (Exceptions.Bad_footprint __POS__) in raise (Exceptions.Bad_footprint __POS__) in
@ -295,7 +297,7 @@ and array_case_analysis_index pname tenv orig_prop
index off inst_arr inst index off inst_arr inst
= =
let check_sound t' = let check_sound t' =
if not (Sil.typ_equal typ_cont t' || array_cont == []) if not (Typ.equal typ_cont t' || array_cont == [])
then raise (Exceptions.Bad_footprint __POS__) in then raise (Exceptions.Bad_footprint __POS__) in
let index_in_array = let index_in_array =
IList.exists (fun (i, _) -> Prover.check_equal Prop.prop_emp index i) array_cont in IList.exists (fun (i, _) -> Prover.check_equal Prop.prop_emp index i) array_cont in
@ -306,7 +308,7 @@ and array_case_analysis_index pname tenv orig_prop
if index_in_array then if index_in_array then
let array_default = Sil.Earray (array_len, array_cont, inst_arr) in let array_default = Sil.Earray (array_len, array_cont, inst_arr) in
let typ_default = Sil.Tarray (typ_cont, typ_array_len) in let typ_default = Typ.Tarray (typ_cont, typ_array_len) in
[([], array_default, typ_default)] [([], array_default, typ_default)]
else if !Config.footprint then begin else if !Config.footprint then begin
let atoms, elem_se, elem_typ = let atoms, elem_se, elem_typ =
@ -315,7 +317,7 @@ and array_case_analysis_index pname tenv orig_prop
check_sound elem_typ; check_sound elem_typ;
let cont_new = IList.sort Sil.exp_strexp_compare ((index, elem_se):: array_cont) in let cont_new = IList.sort Sil.exp_strexp_compare ((index, elem_se):: array_cont) in
let array_new = Sil.Earray (array_len, cont_new, inst_arr) in let array_new = Sil.Earray (array_len, cont_new, inst_arr) in
let typ_new = Sil.Tarray (elem_typ, typ_array_len) in let typ_new = Typ.Tarray (elem_typ, typ_array_len) in
[(atoms, array_new, typ_new)] [(atoms, array_new, typ_new)]
end end
else begin else begin
@ -328,7 +330,7 @@ and array_case_analysis_index pname tenv orig_prop
check_sound elem_typ; check_sound elem_typ;
let cont_new = IList.sort Sil.exp_strexp_compare ((index, elem_se):: array_cont) in let cont_new = IList.sort Sil.exp_strexp_compare ((index, elem_se):: array_cont) in
let array_new = Sil.Earray (array_len, cont_new, inst_arr) in let array_new = Sil.Earray (array_len, cont_new, inst_arr) in
let typ_new = Sil.Tarray (elem_typ, typ_array_len) in let typ_new = Typ.Tarray (elem_typ, typ_array_len) in
[(atoms, array_new, typ_new)] [(atoms, array_new, typ_new)]
end in end in
let rec handle_case acc isel_seen_rev = function let rec handle_case acc isel_seen_rev = function
@ -343,7 +345,7 @@ and array_case_analysis_index pname tenv orig_prop
let atoms_new = Sil.Aeq (index, i) :: atoms' in let atoms_new = Sil.Aeq (index, i) :: atoms' in
let isel_new = list_rev_and_concat isel_seen_rev ((i, se'):: isel_unseen) in let isel_new = list_rev_and_concat isel_seen_rev ((i, se'):: isel_unseen) in
let array_new = Sil.Earray (array_len, isel_new, inst_arr) in let array_new = Sil.Earray (array_len, isel_new, inst_arr) in
let typ_new = Sil.Tarray (typ', typ_array_len) in let typ_new = Typ.Tarray (typ', typ_array_len) in
(atoms_new, array_new, typ_new):: acc' (atoms_new, array_new, typ_new):: acc'
) [] atoms_se_typ_list in ) [] atoms_se_typ_list in
let acc_new = atoms_se_typ_list' :: acc in let acc_new = atoms_se_typ_list' :: acc in
@ -391,7 +393,7 @@ let strexp_extend_values
else off, [] in else off, [] in
if Config.trace_rearrange then if Config.trace_rearrange then
(L.d_str "entering strexp_extend_values se: "; Sil.d_sexp se; L.d_str " typ: "; (L.d_str "entering strexp_extend_values se: "; Sil.d_sexp se; L.d_str " typ: ";
Sil.d_typ_full typ; L.d_str " off': "; Sil.d_offset_list off'; Typ.d_full typ; L.d_str " off': "; Sil.d_offset_list off';
L.d_strln (if footprint_part then " FP" else " RE")); L.d_strln (if footprint_part then " FP" else " RE"));
let atoms_se_typ_list = let atoms_se_typ_list =
_strexp_extend_values _strexp_extend_values
@ -438,11 +440,11 @@ let mk_ptsto_exp_footprint
| Config.Clang -> Sil.Subtype.exact | Config.Clang -> Sil.Subtype.exact
| Config.Java -> Sil.Subtype.subtypes in | Config.Java -> Sil.Subtype.subtypes in
let create_ptsto footprint_part off0 = match root, off0, typ with let create_ptsto footprint_part off0 = match root, off0, typ with
| Sil.Lvar pvar, [], Sil.Tfun _ -> | Sil.Lvar pvar, [], Typ.Tfun _ ->
let fun_name = Procname.from_string_c_fun (Mangled.to_string (Pvar.get_name pvar)) in let fun_name = Procname.from_string_c_fun (Mangled.to_string (Pvar.get_name pvar)) in
let fun_exp = Sil.Const (Sil.Cfun fun_name) in let fun_exp = Sil.Const (Sil.Cfun fun_name) in
([], Prop.mk_ptsto root (Sil.Eexp (fun_exp, inst)) (Sil.Sizeof (typ, None, st))) ([], Prop.mk_ptsto root (Sil.Eexp (fun_exp, inst)) (Sil.Sizeof (typ, None, st)))
| _, [], Sil.Tfun _ -> | _, [], Typ.Tfun _ ->
let atoms, se, t = let atoms, se, t =
create_struct_values create_struct_values
pname tenv orig_prop footprint_part Ident.kfootprint max_stamp typ off0 inst in pname tenv orig_prop footprint_part Ident.kfootprint max_stamp typ off0 inst in
@ -472,7 +474,7 @@ let prop_iter_check_fields_ptsto_shallow iter lexp =
(match se with (match se with
| Sil.Estruct (fsel, _) -> | Sil.Estruct (fsel, _) ->
(try (try
let _, se' = IList.find (fun (fld', _) -> Sil.fld_equal fld fld') fsel in let _, se' = IList.find (fun (fld', _) -> Ident.fieldname_equal fld fld') fsel in
check_offset se' off' check_offset se' off'
with Not_found -> Some fld) with Not_found -> Some fld)
| _ -> Some fld) | _ -> Some fld)
@ -621,7 +623,7 @@ let add_guarded_by_constraints prop lexp pdesc =
let annot_extract_guarded_by_str (annot, _) = let annot_extract_guarded_by_str (annot, _) =
if Annotations.annot_ends_with annot Annotations.guarded_by if Annotations.annot_ends_with annot Annotations.guarded_by
then then
match annot.Sil.parameters with match annot.Typ.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
| _ -> | _ ->
@ -930,14 +932,14 @@ let iter_rearrange_pe_dllseg_last recurse_on_iters default_case_iter iter para_d
let type_at_offset texp off = let type_at_offset texp off =
let rec strip_offset off typ = match off, typ with let rec strip_offset off typ = match off, typ with
| [], _ -> Some typ | [], _ -> Some typ
| (Sil.Off_fld (f, _)):: off', Sil.Tstruct { Sil.instance_fields } -> | (Sil.Off_fld (f, _)):: off', Typ.Tstruct { Typ.instance_fields } ->
(try (try
let typ' = let typ' =
(fun (_, y, _) -> y) (fun (_, y, _) -> y)
(IList.find (fun (f', _, _) -> Ident.fieldname_equal f f') instance_fields) in (IList.find (fun (f', _, _) -> Ident.fieldname_equal f f') instance_fields) in
strip_offset off' typ' strip_offset off' typ'
with Not_found -> None) with Not_found -> None)
| (Sil.Off_index _) :: off', Sil.Tarray (typ', _) -> | (Sil.Off_index _) :: off', Typ.Tarray (typ', _) ->
strip_offset off' typ' strip_offset off' typ'
| _ -> None in | _ -> None in
match texp with match texp with
@ -950,10 +952,10 @@ let type_at_offset texp off =
let check_type_size pname prop texp off typ_from_instr = let check_type_size pname prop texp off typ_from_instr =
L.d_strln_color Orange "check_type_size"; L.d_strln_color Orange "check_type_size";
L.d_str "off: "; Sil.d_offset_list off; L.d_ln (); L.d_str "off: "; Sil.d_offset_list off; L.d_ln ();
L.d_str "typ_from_instr: "; Sil.d_typ_full typ_from_instr; L.d_ln (); L.d_str "typ_from_instr: "; Typ.d_full typ_from_instr; L.d_ln ();
match type_at_offset texp off with match type_at_offset texp off with
| Some typ_of_object -> | Some typ_of_object ->
L.d_str "typ_o: "; Sil.d_typ_full typ_of_object; L.d_ln (); L.d_str "typ_o: "; Typ.d_full typ_of_object; L.d_ln ();
if Prover.type_size_comparable typ_from_instr typ_of_object && Prover.check_type_size_leq typ_from_instr typ_of_object = false if Prover.type_size_comparable typ_from_instr typ_of_object && Prover.check_type_size_leq typ_from_instr typ_of_object = false
then begin then begin
let deref_str = Localise.deref_str_pointer_size_mismatch typ_from_instr typ_of_object in let deref_str = Localise.deref_str_pointer_size_mismatch typ_from_instr typ_of_object in
@ -980,12 +982,13 @@ let rec iter_rearrange
pname tenv lexp typ_from_instr prop iter pname tenv lexp typ_from_instr prop iter
inst: (Sil.offset list) Prop.prop_iter list = inst: (Sil.offset list) Prop.prop_iter list =
let typ = match Sil.exp_get_offsets lexp with let typ = match Sil.exp_get_offsets lexp with
| Sil.Off_fld (f, ((Sil.Tstruct _) as struct_typ)) :: _ -> (* access through field: get the struct type from the field *) | Sil.Off_fld (f, ((Typ.Tstruct _) as struct_typ)) :: _ ->
(* access through field: get the struct type from the field *)
if Config.trace_rearrange then begin if Config.trace_rearrange then begin
L.d_increase_indent 1; L.d_increase_indent 1;
L.d_str "iter_rearrange: root of lexp accesses field "; L.d_strln (Ident.fieldname_to_string f); L.d_str "iter_rearrange: root of lexp accesses field "; L.d_strln (Ident.fieldname_to_string f);
L.d_str " type from instruction: "; Sil.d_typ_full typ_from_instr; L.d_ln(); L.d_str " type from instruction: "; Typ.d_full typ_from_instr; L.d_ln();
L.d_str " struct type from field: "; Sil.d_typ_full struct_typ; L.d_ln(); L.d_str " struct type from field: "; Typ.d_full struct_typ; L.d_ln();
L.d_decrease_indent 1; L.d_decrease_indent 1;
L.d_ln(); L.d_ln();
end; end;
@ -996,7 +999,7 @@ let rec iter_rearrange
L.d_increase_indent 1; L.d_increase_indent 1;
L.d_strln "entering iter_rearrange"; L.d_strln "entering iter_rearrange";
L.d_str "lexp: "; Sil.d_exp lexp; L.d_ln (); L.d_str "lexp: "; Sil.d_exp lexp; L.d_ln ();
L.d_str "typ: "; Sil.d_typ_full typ; L.d_ln (); L.d_str "typ: "; Typ.d_full typ; L.d_ln ();
L.d_strln "prop:"; Prop.d_prop prop; L.d_ln (); L.d_strln "prop:"; Prop.d_prop prop; L.d_ln ();
L.d_strln "iter:"; Prop.d_prop (Prop.prop_iter_to_prop iter); L.d_strln "iter:"; Prop.d_prop (Prop.prop_iter_to_prop iter);
L.d_ln (); L.d_ln () L.d_ln (); L.d_ln ()
@ -1279,6 +1282,6 @@ let pp_off fmt off =
| Sil.Off_index e -> F.fprintf fmt "%a " (Sil.pp_exp pe_text) e) off | Sil.Off_index e -> F.fprintf fmt "%a " (Sil.pp_exp pe_text) e) off
let sort_ftl ftl = let sort_ftl ftl =
let compare (f1, _) (f2, _) = Sil.fld_compare f1 f2 in let compare (f1, _) (f2, _) = Ident.fieldname_compare f1 f2 in
IList.sort compare ftl IList.sort compare ftl
*) *)

@ -29,5 +29,5 @@ val check_call_to_objc_block_error :
and the path (an [offsetlist]) which leads to [lexp] as the iterator state. *) and the path (an [offsetlist]) which leads to [lexp] as the iterator state. *)
val rearrange : val rearrange :
?report_deref_errors:bool -> Cfg.Procdesc.t -> Tenv.t -> Sil.exp -> ?report_deref_errors:bool -> Cfg.Procdesc.t -> Tenv.t -> Sil.exp ->
Sil.typ -> Prop.normal Prop.t -> Typ.t -> Prop.normal Prop.t ->
Location.t -> (Sil.offset list) Prop.prop_iter list Location.t -> (Sil.offset list) Prop.prop_iter list

@ -26,7 +26,7 @@ let tenv_key, summary_key, cfg_key, trace_key, cg_key,
799050016, 579094948, 972393003 799050016, 579094948, 972393003
(** version of the binary files, to be incremented for each change *) (** version of the binary files, to be incremented for each change *)
let version = 25 let version = 26
(** Retry the function while an exception filtered is thrown, (** Retry the function while an exception filtered is thrown,

@ -324,7 +324,7 @@ module CallSiteSet = PrettyPrintable.MakePPSet(struct
let pp_element = pp_call_site let pp_element = pp_call_site
end) end)
type call_summary = CallSiteSet.t Sil.AnnotMap.t type call_summary = CallSiteSet.t Typ.AnnotMap.t
(** Payload: results of some analysis *) (** Payload: results of some analysis *)
type payload = type payload =
@ -425,14 +425,14 @@ let get_signature summary =
IList.iter IList.iter
(fun (p, typ) -> (fun (p, typ) ->
let pp_name f () = F.fprintf f "%a" Mangled.pp p in let pp_name f () = F.fprintf f "%a" Mangled.pp p in
let pp f () = Sil.pp_type_decl pe_text pp_name Sil.pp_exp f typ in let pp f () = Typ.pp_decl pe_text pp_name f typ in
let decl = pp_to_string pp () in let decl = pp_to_string pp () in
s := if !s = "" then decl else !s ^ ", " ^ decl) s := if !s = "" then decl else !s ^ ", " ^ decl)
summary.attributes.ProcAttributes.formals; summary.attributes.ProcAttributes.formals;
let pp_procname f () = F.fprintf f "%a" let pp_procname f () = F.fprintf f "%a"
Procname.pp summary.attributes.ProcAttributes.proc_name in Procname.pp summary.attributes.ProcAttributes.proc_name in
let pp f () = let pp f () =
Sil.pp_type_decl pe_text pp_procname Sil.pp_exp f summary.attributes.ProcAttributes.ret_type in Typ.pp_decl pe_text pp_procname f summary.attributes.ProcAttributes.ret_type in
let decl = pp_to_string pp () in let decl = pp_to_string pp () in
decl ^ "(" ^ !s ^ ")" decl ^ "(" ^ !s ^ ")"

@ -122,7 +122,7 @@ type call_site = Procname.t * Location.t
module CallSiteSet : PrettyPrintable.PPSet with type elt = call_site module CallSiteSet : PrettyPrintable.PPSet with type elt = call_site
type call_summary = CallSiteSet.t Sil.AnnotMap.t type call_summary = CallSiteSet.t Typ.AnnotMap.t
(** Payload: results of some analysis *) (** Payload: results of some analysis *)
type payload = type payload =
@ -164,10 +164,10 @@ val get_proc_name : summary -> Procname.t
val get_attributes : summary -> ProcAttributes.t val get_attributes : summary -> ProcAttributes.t
(** Get the return type of the procedure *) (** Get the return type of the procedure *)
val get_ret_type : summary -> Sil.typ val get_ret_type : summary -> Typ.t
(** Get the formal paramters of the procedure *) (** Get the formal paramters of the procedure *)
val get_formals : summary -> (Mangled.t * Sil.typ) list val get_formals : summary -> (Mangled.t * Typ.t) list
(** Get the flag with the given key for the procedure, if any *) (** Get the flag with the given key for the procedure, if any *)
val get_flag : Procname.t -> string -> string option val get_flag : Procname.t -> string -> string option
@ -185,7 +185,7 @@ val get_signature : summary -> string
val get_specs : Procname.t -> Prop.normal spec list val get_specs : Procname.t -> Prop.normal spec list
(** Return the specs and formal parameters for the proc in the spec table *) (** Return the specs and formal parameters for the proc in the spec table *)
val get_specs_formals : Procname.t -> Prop.normal spec list * (Mangled.t * Sil.typ) list val get_specs_formals : Procname.t -> Prop.normal spec list * (Mangled.t * Typ.t) list
(** Get the specs from the payload of the summary. *) (** Get the specs from the payload of the summary. *)
val get_specs_from_payload : summary -> Prop.normal spec list val get_specs_from_payload : summary -> Prop.normal spec list

@ -17,30 +17,30 @@ module F = Format
let rec fldlist_assoc fld = function let rec fldlist_assoc fld = function
| [] -> raise Not_found | [] -> raise Not_found
| (fld', x, _):: l -> if Sil.fld_equal fld fld' then x else fldlist_assoc fld l | (fld', x, _):: l -> if Ident.fieldname_equal fld fld' then x else fldlist_assoc fld l
let rec unroll_type tenv typ off = let rec unroll_type tenv typ off =
match (typ, off) with match (typ, off) with
| Sil.Tvar _, _ -> | Typ.Tvar _, _ ->
let typ' = Tenv.expand_type tenv typ in let typ' = Tenv.expand_type tenv typ in
unroll_type tenv typ' off unroll_type tenv typ' off
| Sil.Tstruct { Sil.instance_fields; static_fields }, Sil.Off_fld (fld, _) -> | Typ.Tstruct { Typ.instance_fields; static_fields }, Sil.Off_fld (fld, _) ->
begin begin
try fldlist_assoc fld (instance_fields @ static_fields) try fldlist_assoc fld (instance_fields @ static_fields)
with Not_found -> with Not_found ->
L.d_strln ".... Invalid Field Access ...."; L.d_strln ".... Invalid Field Access ....";
L.d_strln ("Fld : " ^ Ident.fieldname_to_string fld); L.d_strln ("Fld : " ^ Ident.fieldname_to_string fld);
L.d_str "Type : "; Sil.d_typ_full typ; L.d_ln (); L.d_str "Type : "; Typ.d_full typ; L.d_ln ();
raise (Exceptions.Bad_footprint __POS__) raise (Exceptions.Bad_footprint __POS__)
end end
| Sil.Tarray (typ', _), Sil.Off_index _ -> | Typ.Tarray (typ', _), Sil.Off_index _ ->
typ' typ'
| _, Sil.Off_index (Sil.Const (Sil.Cint i)) when IntLit.iszero i -> | _, Sil.Off_index (Sil.Const (Sil.Cint i)) when IntLit.iszero i ->
typ typ
| _ -> | _ ->
L.d_strln ".... Invalid Field Access ...."; L.d_strln ".... Invalid Field Access ....";
L.d_str "Fld : "; Sil.d_offset off; L.d_ln (); L.d_str "Fld : "; Sil.d_offset off; L.d_ln ();
L.d_str "Type : "; Sil.d_typ_full typ; L.d_ln (); L.d_str "Type : "; Typ.d_full typ; L.d_ln ();
assert false assert false
(** Given a node, returns a list of pvar of blocks that have been nullified in the block. *) (** Given a node, returns a list of pvar of blocks that have been nullified in the block. *)
@ -88,7 +88,7 @@ let rec apply_offlist
L.d_strln ".... Invalid Field ...."; L.d_strln ".... Invalid Field ....";
L.d_str "strexp : "; Sil.d_sexp strexp; L.d_ln (); L.d_str "strexp : "; Sil.d_sexp strexp; L.d_ln ();
L.d_str "offlist : "; Sil.d_offset_list offlist; L.d_ln (); L.d_str "offlist : "; Sil.d_offset_list offlist; L.d_ln ();
L.d_str "type : "; Sil.d_typ_full typ; L.d_ln (); L.d_str "type : "; Typ.d_full typ; L.d_ln ();
L.d_str "prop : "; Prop.d_prop p; L.d_ln (); L.d_ln () in L.d_str "prop : "; Prop.d_prop p; L.d_ln (); L.d_ln () in
match offlist, strexp with match offlist, strexp with
| [], Sil.Eexp (e, inst_curr) -> | [], Sil.Eexp (e, inst_curr) ->
@ -143,7 +143,7 @@ let rec apply_offlist
let typ' = Tenv.expand_type tenv typ in let typ' = Tenv.expand_type tenv typ in
let struct_typ = let struct_typ =
match typ' with match typ' with
| Sil.Tstruct struct_typ -> | Typ.Tstruct struct_typ ->
struct_typ struct_typ
| _ -> assert false in | _ -> assert false in
let t' = unroll_type tenv typ (Sil.Off_fld (fld, fld_typ)) in let t' = unroll_type tenv typ (Sil.Off_fld (fld, fld_typ)) in
@ -153,12 +153,14 @@ let rec apply_offlist
apply_offlist apply_offlist
pdesc tenv p fp_root nullify_struct pdesc tenv p fp_root nullify_struct
(root_lexp, se', t') offlist' f inst lookup_inst in (root_lexp, se', t') offlist' f inst lookup_inst in
let replace_fse fse = if Sil.fld_equal fld (fst fse) then (fld, res_se') else fse in let replace_fse fse =
if Ident.fieldname_equal fld (fst fse) then (fld, res_se') else fse in
let res_se = Sil.Estruct (IList.map replace_fse fsel, inst') in let res_se = Sil.Estruct (IList.map replace_fse fsel, inst') in
let replace_fta (f, t, a) = if Sil.fld_equal fld f then (fld, res_t', a) else (f, t, a) in let replace_fta (f, t, a) =
let instance_fields' = IList.map replace_fta struct_typ.Sil.instance_fields in if Ident.fieldname_equal fld f then (fld, res_t', a) else (f, t, a) in
let instance_fields' = IList.map replace_fta struct_typ.Typ.instance_fields in
let res_t = let res_t =
Sil.Tstruct { struct_typ with Sil.instance_fields = instance_fields' } in Typ.Tstruct { struct_typ with Typ.instance_fields = instance_fields' } in
(res_e', res_se, res_t, res_pred_insts_op') (res_e', res_se, res_t, res_pred_insts_op')
with Not_found -> with Not_found ->
pp_error(); pp_error();
@ -174,7 +176,7 @@ let rec apply_offlist
let nidx = Prop.exp_normalize_prop p idx in let nidx = Prop.exp_normalize_prop p idx in
begin begin
let typ' = Tenv.expand_type tenv typ in let typ' = Tenv.expand_type tenv typ in
let t', len' = match typ' with Sil.Tarray (t', len') -> (t', len') | _ -> assert false in let t', len' = match typ' with Typ.Tarray (t', len') -> (t', len') | _ -> assert false in
try try
let idx_ese', se' = IList.find (fun ese -> Prover.check_equal p nidx (fst ese)) esel in let idx_ese', se' = IList.find (fun ese -> Prover.check_equal p nidx (fst ese)) esel in
let res_e', res_se', res_t', res_pred_insts_op' = let res_e', res_se', res_t', res_pred_insts_op' =
@ -186,7 +188,7 @@ let rec apply_offlist
then (idx_ese', res_se') then (idx_ese', res_se')
else ese in else ese in
let res_se = Sil.Earray (len, IList.map replace_ese esel, inst1) in let res_se = Sil.Earray (len, IList.map replace_ese esel, inst1) in
let res_t = Sil.Tarray (res_t', len') in let res_t = Typ.Tarray (res_t', len') in
(res_e', res_se, res_t, res_pred_insts_op') (res_e', res_se, res_t, res_pred_insts_op')
with Not_found -> with Not_found ->
(* return a nondeterministic value if the index is not found after rearrangement *) (* return a nondeterministic value if the index is not found after rearrangement *)
@ -498,7 +500,7 @@ let resolve_method tenv class_name proc_name =
let right_proc_name = let right_proc_name =
Procname.replace_class proc_name (Typename.name class_name) in Procname.replace_class proc_name (Typename.name class_name) in
match Tenv.lookup tenv class_name with match Tenv.lookup tenv class_name with
| Some { Sil.csu = Csu.Class _; def_methods; superclasses } -> | Some { Typ.csu = Csu.Class _; def_methods; superclasses } ->
if method_exists right_proc_name def_methods then if method_exists right_proc_name def_methods then
Some right_proc_name Some right_proc_name
else else
@ -526,8 +528,8 @@ let resolve_typename prop receiver_exp =
| _ :: hpreds -> loop hpreds in | _ :: hpreds -> loop hpreds in
loop (Prop.get_sigma prop) in loop (Prop.get_sigma prop) in
match typexp_opt with match typexp_opt with
| Some (Sil.Sizeof (Sil.Tstruct { Sil.struct_name = None }, _, _)) -> None | Some (Sil.Sizeof (Typ.Tstruct { Typ.struct_name = None }, _, _)) -> None
| Some (Sil.Sizeof (Sil.Tstruct { Sil.csu = Csu.Class ck; struct_name = Some name }, _, _)) -> | Some (Sil.Sizeof (Typ.Tstruct { Typ.csu = Csu.Class ck; struct_name = Some name }, _, _)) ->
Some (Typename.TN_csu (Csu.Class ck, name)) Some (Typename.TN_csu (Csu.Class ck, name))
| _ -> None | _ -> None
@ -542,7 +544,7 @@ let resolve_virtual_pname tenv prop actuals callee_pname call_flags : Procname.t
| Procname.Java pname_java -> | Procname.Java pname_java ->
begin begin
match Tenv.proc_extract_declaring_class_typ tenv pname_java with match Tenv.proc_extract_declaring_class_typ tenv pname_java with
| Some struct_typ -> Sil.Tptr (Tstruct struct_typ, Pk_pointer) | Some struct_typ -> Typ.Tptr (Tstruct struct_typ, Pk_pointer)
| None -> fallback_typ | None -> fallback_typ
end end
| _ -> | _ ->
@ -550,7 +552,7 @@ let resolve_virtual_pname tenv prop actuals callee_pname call_flags : Procname.t
let receiver_types_equal pname actual_receiver_typ = let receiver_types_equal pname actual_receiver_typ =
(* the type of the receiver according to the function signature *) (* the type of the receiver according to the function signature *)
let formal_receiver_typ = get_receiver_typ pname actual_receiver_typ in let formal_receiver_typ = get_receiver_typ pname actual_receiver_typ in
Sil.typ_equal formal_receiver_typ actual_receiver_typ in Typ.equal formal_receiver_typ actual_receiver_typ in
let do_resolve called_pname receiver_exp actual_receiver_typ = let do_resolve called_pname receiver_exp actual_receiver_typ =
if receiver_types_equal called_pname actual_receiver_typ if receiver_types_equal called_pname actual_receiver_typ
then resolve receiver_exp called_pname prop then resolve receiver_exp called_pname prop
@ -823,7 +825,7 @@ let add_constraints_on_retval pdesc prop ret_exp ~has_nullable_annot typ callee_
prop (* don't assume nonnull if the procedure is annotated with @Nullable *) prop (* don't assume nonnull if the procedure is annotated with @Nullable *)
else else
match typ with match typ with
| Sil.Tptr _ -> Prop.conjoin_neq exp Sil.exp_zero prop | Typ.Tptr _ -> Prop.conjoin_neq exp Sil.exp_zero prop
| _ -> prop in | _ -> prop in
let add_tainted_post ret_exp callee_pname prop = let add_tainted_post ret_exp callee_pname prop =
Prop.add_or_replace_exp_attribute prop ret_exp (Sil.Ataint callee_pname) in Prop.add_or_replace_exp_attribute prop ret_exp (Sil.Ataint callee_pname) in
@ -944,7 +946,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 ->
Sil.item_annotation_empty Typ.item_annotation_empty
let execute_set ?(report_deref_errors=true) pname pdesc tenv lhs_exp typ rhs_exp loc prop_ = let execute_set ?(report_deref_errors=true) pname pdesc tenv lhs_exp typ rhs_exp loc prop_ =
let execute_set_ pdesc tenv rhs_exp acc_in iter = let execute_set_ pdesc tenv rhs_exp acc_in iter =
@ -1036,7 +1038,7 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
true_branch && not skip_loop in true_branch && not skip_loop in
(* in comparisons, nil is translated as (void * ) 0 rather than 0 *) (* in comparisons, nil is translated as (void * ) 0 rather than 0 *)
let is_comparison_to_nil = function let is_comparison_to_nil = function
| Sil.Cast ((Sil.Tptr (Sil.Tvoid, _)), exp) -> | Sil.Cast ((Typ.Tptr (Typ.Tvoid, _)), exp) ->
!Config.curr_language = Config.Clang && Sil.exp_is_zero exp !Config.curr_language = Config.Clang && Sil.exp_is_zero exp
| _ -> false in | _ -> false in
match Prop.exp_normalize_prop Prop.prop_emp cond with match Prop.exp_normalize_prop Prop.prop_emp cond with
@ -1052,13 +1054,13 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
(* iOS: check that NSNumber *'s are not used in conditionals without comparing to nil *) (* iOS: check that NSNumber *'s are not used in conditionals without comparing to nil *)
let lhs_normal = Prop.exp_normalize_prop prop__ lhs in let lhs_normal = Prop.exp_normalize_prop prop__ lhs in
let is_nsnumber = function let is_nsnumber = function
| Sil.Tvar (Typename.TN_csu (Csu.Class _, name)) -> | Typ.Tvar (Typename.TN_csu (Csu.Class _, name)) ->
Mangled.to_string name = "NSNumber" Mangled.to_string name = "NSNumber"
| _ -> false in | _ -> false in
let lhs_is_ns_ptr () = let lhs_is_ns_ptr () =
IList.exists IList.exists
(function (function
| Sil.Hpointsto (_, Sil.Eexp (exp, _), Sil.Sizeof (Sil.Tptr (typ, _), _, _)) -> | Sil.Hpointsto (_, Sil.Eexp (exp, _), Sil.Sizeof (Typ.Tptr (typ, _), _, _)) ->
Sil.exp_equal exp lhs_normal && is_nsnumber typ Sil.exp_equal exp lhs_normal && is_nsnumber typ
| _ -> false) | _ -> false)
(Prop.get_sigma prop__) in (Prop.get_sigma prop__) in
@ -1091,9 +1093,9 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
| None -> | None ->
let ret_typ = let ret_typ =
match Tenv.proc_extract_return_typ tenv callee_pname_java with match Tenv.proc_extract_return_typ tenv callee_pname_java with
| Some (Sil.Tstruct _ as typ) -> Sil.Tptr (typ, Pk_pointer) | Some (Typ.Tstruct _ as typ) -> Typ.Tptr (typ, Pk_pointer)
| Some typ -> typ | Some typ -> typ
| None -> Sil.Tvoid in | None -> Typ.Tvoid in
let ret_annots = load_ret_annots callee_pname in let ret_annots = load_ret_annots callee_pname in
exec_skip_call resolved_pname ret_annots ret_typ exec_skip_call resolved_pname ret_annots ret_typ
| Some summary when call_should_be_skipped resolved_pname summary -> | Some summary when call_should_be_skipped resolved_pname summary ->
@ -1121,9 +1123,9 @@ let rec sym_exec tenv current_pdesc _instr (prop_: Prop.normal Prop.t) path
| None -> | None ->
let ret_typ = let ret_typ =
match Tenv.proc_extract_return_typ tenv callee_pname_java with match Tenv.proc_extract_return_typ tenv callee_pname_java with
| Some (Sil.Tstruct _ as typ) -> Sil.Tptr (typ, Pk_pointer) | Some (Typ.Tstruct _ as typ) -> Typ.Tptr (typ, Pk_pointer)
| Some typ -> typ | Some typ -> typ
| None -> Sil.Tvoid in | None -> Typ.Tvoid in
let ret_annots = load_ret_annots callee_pname in let ret_annots = load_ret_annots callee_pname in
exec_skip_call ret_annots ret_typ exec_skip_call ret_annots ret_typ
| Some summary when call_should_be_skipped pname summary -> | Some summary when call_should_be_skipped pname summary ->
@ -1204,7 +1206,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 Sil.item_annotation_empty Builtin.{ unknown_or_scan_call ~is_scan:false None Typ.item_annotation_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
@ -1304,11 +1306,11 @@ and add_constraints_on_actuals_by_ref tenv prop actuals_by_ref callee_pname call
else else
if !Config.footprint then if !Config.footprint then
let prop', abduced_strexp = match actual_typ with let prop', abduced_strexp = match actual_typ with
| Sil.Tptr ((Sil.Tstruct _) as typ, _) -> | Typ.Tptr ((Typ.Tstruct _) as typ, _) ->
(* for struct types passed by reference, do abduction on the fields of the (* for struct types passed by reference, do abduction on the fields of the
struct *) struct *)
add_struct_value_to_footprint tenv abducted_ref_pv typ prop add_struct_value_to_footprint tenv abducted_ref_pv typ prop
| Sil.Tptr (typ, _) -> | Typ.Tptr (typ, _) ->
(* for pointer types passed by reference, do abduction directly on the pointer *) (* for pointer types passed by reference, do abduction directly on the pointer *)
let (prop', fresh_fp_var) = let (prop', fresh_fp_var) =
add_to_footprint abducted_ref_pv typ prop in add_to_footprint abducted_ref_pv typ prop in
@ -1316,7 +1318,7 @@ and add_constraints_on_actuals_by_ref tenv prop actuals_by_ref callee_pname call
| typ -> | typ ->
failwith failwith
("No need for abduction on non-pointer type " ^ ("No need for abduction on non-pointer type " ^
(Sil.typ_to_string typ)) in (Typ.to_string typ)) in
(* replace [actual] |-> _ with [actual] |-> [fresh_fp_var] *) (* replace [actual] |-> _ with [actual] |-> [fresh_fp_var] *)
let filtered_sigma = let filtered_sigma =
IList.map IList.map
@ -1353,7 +1355,7 @@ and add_constraints_on_actuals_by_ref tenv prop actuals_by_ref callee_pname call
let havoc_actual_by_ref (actual, actual_typ) prop = let havoc_actual_by_ref (actual, actual_typ) prop =
let actual_pt_havocd_var = let actual_pt_havocd_var =
let havocd_var = Sil.Var (Ident.create_fresh Ident.kprimed) in let havocd_var = Sil.Var (Ident.create_fresh Ident.kprimed) in
let sizeof_exp = Sil.Sizeof (Sil.typ_strip_ptr actual_typ, None, Sil.Subtype.subtypes) in let sizeof_exp = Sil.Sizeof (Typ.strip_ptr actual_typ, None, Sil.Subtype.subtypes) in
Prop.mk_ptsto actual (Sil.Eexp (havocd_var, Sil.Inone)) sizeof_exp in Prop.mk_ptsto actual (Sil.Eexp (havocd_var, Sil.Inone)) sizeof_exp in
replace_actual_hpred actual actual_pt_havocd_var prop in replace_actual_hpred actual actual_pt_havocd_var prop in
IList.fold_left (fun p var -> havoc_actual_by_ref var p) prop actuals_by_ref IList.fold_left (fun p var -> havoc_actual_by_ref var p) prop actuals_by_ref
@ -1421,7 +1423,7 @@ and unknown_or_scan_call ~is_scan ret_type_option ret_annots
let actuals_by_ref = let actuals_by_ref =
IList.filter IList.filter
(function (function
| Sil.Lvar _, Sil.Tptr _ -> true | Sil.Lvar _, Typ.Tptr _ -> true
| _ -> false) | _ -> false)
args in args in
let has_nullable_annot = Annotations.ia_is_nullable ret_annots in let has_nullable_annot = Annotations.ia_is_nullable ret_annots in
@ -1513,8 +1515,8 @@ and sym_exec_objc_getter field_name ret_typ tenv ret_ids pdesc pname loc args pr
match args with match args with
| [(lexp, typ)] -> | [(lexp, typ)] ->
let typ' = (match Tenv.expand_type tenv typ with let typ' = (match Tenv.expand_type tenv typ with
| Sil.Tstruct _ as s -> s | Typ.Tstruct _ as s -> s
| Sil.Tptr (t, _) -> Tenv.expand_type tenv t | Typ.Tptr (t, _) -> Tenv.expand_type tenv t
| _ -> assert false) in | _ -> assert false) in
let field_access_exp = Sil.Lfield (lexp, field_name, typ') in let field_access_exp = Sil.Lfield (lexp, field_name, typ') in
execute_letderef execute_letderef
@ -1527,8 +1529,8 @@ and sym_exec_objc_setter field_name _ tenv _ pdesc pname loc args prop =
match args with match args with
| (lexp1, typ1) :: (lexp2, typ2)::_ -> | (lexp1, typ1) :: (lexp2, typ2)::_ ->
let typ1' = (match Tenv.expand_type tenv typ1 with let typ1' = (match Tenv.expand_type tenv typ1 with
| Sil.Tstruct _ as s -> s | Typ.Tstruct _ as s -> s
| Sil.Tptr (t, _) -> Tenv.expand_type tenv t | Typ.Tptr (t, _) -> Tenv.expand_type tenv t
| _ -> assert false) in | _ -> assert false) in
let field_access_exp = Sil.Lfield (lexp1, field_name, typ1') in let field_access_exp = Sil.Lfield (lexp1, field_name, typ1') in
execute_set ~report_deref_errors:false pname pdesc tenv field_access_exp typ2 lexp2 loc prop execute_set ~report_deref_errors:false pname pdesc tenv field_access_exp typ2 lexp2 loc prop
@ -1554,8 +1556,8 @@ and proc_call summary {Builtin.pdesc; tenv; prop_= pre; path; ret_ids; args= act
let check_return_value_ignored () = let check_return_value_ignored () =
(* check if the return value of the call is ignored, and issue a warning *) (* check if the return value of the call is ignored, and issue a warning *)
let is_ignored = match ret_typ, ret_ids with let is_ignored = match ret_typ, ret_ids with
| Sil.Tvoid, _ -> false | Typ.Tvoid, _ -> false
| Sil.Tint _, _ when not (proc_is_defined callee_pname) -> | Typ.Tint _, _ when not (proc_is_defined callee_pname) ->
(* if the proc returns Tint and is not defined, *) (* if the proc returns Tint and is not defined, *)
(* don't report ignored return value *) (* don't report ignored return value *)
false false
@ -1584,13 +1586,13 @@ and proc_call summary {Builtin.pdesc; tenv; prop_= pre; path; ret_ids; args= act
"likely use of variable-arguments function, or function prototype missing"; "likely use of variable-arguments function, or function prototype missing";
L.d_ln(); L.d_ln();
L.d_str "actual parameters: "; Sil.d_exp_list (IList.map fst actual_pars); L.d_ln (); L.d_str "actual parameters: "; Sil.d_exp_list (IList.map fst actual_pars); L.d_ln ();
L.d_str "formal parameters: "; Sil.d_typ_list formal_types; L.d_ln (); L.d_str "formal parameters: "; Typ.d_list formal_types; L.d_ln ();
actual_pars actual_pars
| [], _ -> | [], _ ->
L.d_str ("**** ERROR: Procedure " ^ Procname.to_string callee_pname); L.d_str ("**** ERROR: Procedure " ^ Procname.to_string callee_pname);
L.d_strln (" mismatch in the number of parameters ****"); L.d_strln (" mismatch in the number of parameters ****");
L.d_str "actual parameters: "; Sil.d_exp_list (IList.map fst actual_pars); L.d_ln (); L.d_str "actual parameters: "; Sil.d_exp_list (IList.map fst actual_pars); L.d_ln ();
L.d_str "formal parameters: "; Sil.d_typ_list formal_types; L.d_ln (); L.d_str "formal parameters: "; Typ.d_list formal_types; L.d_ln ();
raise (Exceptions.Wrong_argument_number __POS__) in raise (Exceptions.Wrong_argument_number __POS__) in
let actual_params = comb actual_pars formal_types in let actual_params = comb actual_pars formal_types in
(* Actual parameters are associated to their formal (* Actual parameters are associated to their formal

@ -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 -> Sil.typ option -> Sil.item_annotation -> Builtin.t val unknown_or_scan_call : is_scan:bool -> Typ.t option -> Typ.item_annotation -> 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

@ -468,8 +468,8 @@ let texp_star texp1 texp2 =
| 0 -> ftal_sub ftal1' ftal2' | 0 -> ftal_sub ftal1' ftal2'
| _ -> ftal_sub ftal1 ftal2' end in | _ -> ftal_sub ftal1 ftal2' end in
let typ_star t1 t2 = match t1, t2 with let typ_star t1 t2 = match t1, t2 with
| Sil.Tstruct { Sil.instance_fields = instance_fields1; csu = csu1 }, | Typ.Tstruct { Typ.instance_fields = instance_fields1; csu = csu1 },
Sil.Tstruct { Sil.instance_fields = instance_fields2; csu = csu2 } when csu1 = csu2 -> Typ.Tstruct { Typ.instance_fields = instance_fields2; csu = csu2 } when csu1 = csu2 ->
if ftal_sub instance_fields1 instance_fields2 then t2 else t1 if ftal_sub instance_fields1 instance_fields2 then t2 else t1
| _ -> t1 in | _ -> t1 in
match texp1, texp2 with match texp1, texp2 with
@ -629,7 +629,7 @@ let prop_get_exn_name pname prop =
let ret_pvar = Sil.Lvar (Pvar.get_ret_pvar pname) in let ret_pvar = Sil.Lvar (Pvar.get_ret_pvar pname) in
let rec search_exn e = function let rec search_exn e = function
| [] -> None | [] -> None
| Sil.Hpointsto (e1, _, Sil.Sizeof (Sil.Tstruct { Sil.struct_name = Some name }, _, _)) :: _ | Sil.Hpointsto (e1, _, Sil.Sizeof (Typ.Tstruct { Typ.struct_name = Some name }, _, _)) :: _
when Sil.exp_equal e1 e -> when Sil.exp_equal e1 e ->
Some (Typename.TN_csu (Csu.Class Csu.Java, name)) Some (Typename.TN_csu (Csu.Class Csu.Java, name))
| _ :: tl -> search_exn e tl in | _ :: tl -> search_exn e tl in

@ -45,5 +45,5 @@ val d_splitting : splitting -> unit
(** Execute the function call and return the list of results with return value *) (** Execute the function call and return the list of results with return value *)
val exe_function_call: val exe_function_call:
ProcAttributes.t -> Tenv.t -> Ident.t list -> Cfg.Procdesc.t -> Procname.t -> Location.t -> ProcAttributes.t -> Tenv.t -> Ident.t list -> Cfg.Procdesc.t -> Procname.t -> Location.t ->
(Sil.exp * Sil.typ) list -> Prop.normal Prop.t -> Paths.Path.t -> (Sil.exp * Typ.t) list -> Prop.normal Prop.t -> Paths.Path.t ->
(Prop.normal Prop.t * Paths.Path.t) list (Prop.normal Prop.t * Paths.Path.t) list

@ -300,7 +300,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 -> Sil.method_annotation_empty | None -> Typ.method_annotation_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 *)
@ -356,8 +356,8 @@ let has_taint_annotation fieldname struct_typ =
let fld_has_taint_annot (fname, _, annot) = let fld_has_taint_annot (fname, _, annot) =
Ident.fieldname_equal fieldname fname && Ident.fieldname_equal fieldname fname &&
(Annotations.ia_is_privacy_source annot || Annotations.ia_is_integrity_source annot) in (Annotations.ia_is_privacy_source annot || Annotations.ia_is_integrity_source annot) in
IList.exists fld_has_taint_annot struct_typ.Sil.instance_fields || IList.exists fld_has_taint_annot struct_typ.Typ.instance_fields ||
IList.exists fld_has_taint_annot struct_typ.Sil.static_fields IList.exists fld_has_taint_annot struct_typ.Typ.static_fields
(* add tainting attributes to a list of paramenters *) (* add tainting attributes to a list of paramenters *)
let get_params_to_taint tainted_param_nums formal_params = let get_params_to_taint tainted_param_nums formal_params =

@ -20,7 +20,7 @@ val accepts_sensitive_params : Procname.t -> ProcAttributes.t option -> (int * S
val tainted_params : Procname.t -> (int * Sil.taint_kind) list val tainted_params : Procname.t -> (int * Sil.taint_kind) list
(** returns the taint_kind of [fieldname] if it has a taint source annotation *) (** returns the taint_kind of [fieldname] if it has a taint source annotation *)
val has_taint_annotation : Ident.fieldname -> Sil.struct_typ -> bool val has_taint_annotation : Ident.fieldname -> Typ.struct_typ -> bool
val add_tainting_attribute : Sil.attribute -> Pvar.t -> Prop.normal Prop.t -> Prop.normal Prop.t val add_tainting_attribute : Sil.attribute -> Pvar.t -> Prop.normal Prop.t -> Prop.normal Prop.t

@ -40,7 +40,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
add_address_taken_pvars rhs_exp astate add_address_taken_pvars rhs_exp astate
| Sil.Call (_, _, actuals, _, _) -> | Sil.Call (_, _, actuals, _, _) ->
let add_actual_by_ref astate_acc = function let add_actual_by_ref astate_acc = function
| actual_exp, Sil.Tptr _ -> add_address_taken_pvars actual_exp astate_acc | actual_exp, Typ.Tptr _ -> add_address_taken_pvars actual_exp astate_acc
| _ -> astate_acc in | _ -> astate_acc in
IList.fold_left add_actual_by_ref astate actuals IList.fold_left add_actual_by_ref astate actuals
| Sil.Set _ | Letderef _ | Prune _ | Nullify _ | Abstract _ | Remove_temps _ | Stackop _ | Sil.Set _ | Letderef _ | Prune _ | Nullify _ | Abstract _ | Remove_temps _ | Stackop _

@ -13,12 +13,12 @@ module F = Format
module L = Logging module L = Logging
module CallSiteSet = AbstractDomain.FiniteSet (Specs.CallSiteSet) module CallSiteSet = AbstractDomain.FiniteSet (Specs.CallSiteSet)
module CallsDomain = AbstractDomain.Map (Sil.AnnotMap) (CallSiteSet) module CallsDomain = AbstractDomain.Map (Typ.AnnotMap) (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 =
{ Sil.class_name = annot_str; parameters = []; } { Typ.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 () =
@ -136,7 +136,7 @@ let is_allocator tenv pname =
let check_attributes check tenv pname = let check_attributes check tenv pname =
let check_class_attributes check tenv = function let check_class_attributes check tenv = function
| Procname.Java java_pname -> | Procname.Java java_pname ->
let check_class_annots { Sil.struct_annotations; } = let check_class_annots { Typ.struct_annotations; } =
check struct_annotations in check struct_annotations in
begin begin
match Tenv.proc_extract_declaring_class_typ tenv java_pname with match Tenv.proc_extract_declaring_class_typ tenv java_pname with
@ -166,7 +166,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.Sil.class_name in let has_annot ia = Annotations.ia_ends_with ia annot.Typ.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
@ -181,7 +181,7 @@ let lookup_annotation_calls annot pname =
| Some { Specs.payload = { Specs.calls = Some call_map; }; } -> | Some { Specs.payload = { Specs.calls = Some call_map; }; } ->
begin begin
try try
Sil.AnnotMap.find annot call_map Typ.AnnotMap.find annot call_map
|> Specs.CallSiteSet.elements |> Specs.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.Sil.class_name = dummy_constructor_annot if annot.Typ.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 Sil.AnnotMap.find annot call_map try Typ.AnnotMap.find annot call_map
with Not_found -> Specs.CallSiteSet.empty in with Not_found -> Specs.CallSiteSet.empty in
if (not (Specs.CallSiteSet.is_empty calls) || method_has_annot annot tenv callee_pname) && if (not (Specs.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 *)
Sil.AnnotMap.fold add_call_for_annot map astate Typ.AnnotMap.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 Sil.AnnotMap.empty tenv callee_pname caller_pname call_site astate add_call Typ.AnnotMap.empty tenv callee_pname caller_pname call_site astate
| Some Domain.Bottom -> | Some Domain.Bottom ->
astate astate
end end
@ -398,14 +398,14 @@ module Interprocedural = struct
let report_src_snk_paths call_map (src_annot_list, snk_annot) = let report_src_snk_paths call_map (src_annot_list, snk_annot) =
let extract_calls_with_annot annot call_map = let extract_calls_with_annot annot call_map =
try try
Sil.AnnotMap.find annot call_map Typ.AnnotMap.find annot call_map
|> Specs.CallSiteSet.elements |> Specs.CallSiteSet.elements
with Not_found -> [] in with Not_found -> [] in
let report_src_snk_path calls src_annot = let report_src_snk_path calls src_annot =
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.Sil.class_name snk_annot.Sil.class_name in report_annotation_stack src_annot.Typ.class_name snk_annot.Typ.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 : Sil.item_annotation * Sil.typ; (** Annotated return type. *) { ret : Typ.item_annotation * Typ.t; (** Annotated return type. *)
params: (Mangled.t * Sil.item_annotation * Sil.typ) list } (** Annotated parameters. *) params: (Mangled.t * Typ.item_annotation * 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 &&
Sil.item_annotation_compare ia1 ia2 = 0 && Typ.item_annotation_compare ia1 ia2 = 0 &&
Sil.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
Sil.item_annotation_compare ia1 ia2 = 0 && Typ.item_annotation_compare ia1 ia2 = 0 &&
Sil.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
let visibleForTesting = "com.google.common.annotations.VisibleForTesting" let visibleForTesting = "com.google.common.annotations.VisibleForTesting"
@ -36,12 +36,12 @@ let suppressLint = "android.annotation.SuppressLint"
let get_field_type_and_annotation fn = function let get_field_type_and_annotation fn = function
| Sil.Tptr (Sil.Tstruct struct_typ, _) | Typ.Tptr (Typ.Tstruct struct_typ, _)
| Sil.Tstruct struct_typ -> | Typ.Tstruct struct_typ ->
(try (try
let (_, t, a) = IList.find (fun (f, _, _) -> let (_, t, a) = IList.find (fun (f, _, _) ->
Sil.fld_equal f fn) Ident.fieldname_equal f fn)
(struct_typ.Sil.instance_fields @ struct_typ.Sil.static_fields) in (struct_typ.Typ.instance_fields @ struct_typ.Typ.static_fields) in
Some (t, a) Some (t, a)
with Not_found -> None) with Not_found -> None)
| _ -> None | _ -> None
@ -49,19 +49,19 @@ let get_field_type_and_annotation fn = function
(** Return the annotations on the declaring class of [pname]. Only works for Java *) (** Return the annotations on the declaring class of [pname]. Only works for Java *)
let get_declaring_class_annotations pname tenv = let get_declaring_class_annotations pname tenv =
match Tenv.proc_extract_declaring_class_typ tenv pname with match Tenv.proc_extract_declaring_class_typ tenv pname with
| Some { Sil.struct_annotations } -> Some struct_annotations | Some { Typ.struct_annotations } -> Some struct_annotations
| None -> None | None -> None
let ia_iter f = 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) : Sil.method_annotation) = let ma_iter f ((ia, ial) : Typ.method_annotation) =
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: Sil.method_annotation) (ma: Typ.method_annotation)
(predicate: Sil.annotation -> bool): bool = (predicate: Typ.annotation -> 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)
@ -69,8 +69,8 @@ let ma_has_annotation_with
!found !found
let ia_has_annotation_with let ia_has_annotation_with
(ia: Sil.item_annotation) (ia: Typ.item_annotation)
(predicate: Sil.annotation -> bool): bool = (predicate: Typ.annotation -> 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)
@ -83,7 +83,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.Sil.class_name filter annot.Typ.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 =
@ -93,17 +93,19 @@ 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.Sil.class_name then found := true) ia; ia_iter (fun a -> if ann_name = a.Typ.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.Sil.class_name then found := Some a) ia; ia_iter (fun a -> if ann_name = a.Typ.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 -> if IList.exists (string_equal a.Sil.class_name) ann_names then found := true) ma; ma_iter (fun a ->
if IList.exists (string_equal a.Typ.class_name) ann_names then found := true
) ma;
!found !found
let initializer_ = "Initializer" let initializer_ = "Initializer"
@ -246,7 +248,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, Sil.item_annotation_empty, typ) :: extract [] parl' (name, Typ.item_annotation_empty, typ) :: extract [] parl'
| [], [] -> | [], [] ->
[] []
| _ :: _, [] -> | _ :: _, [] ->
@ -261,7 +263,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) =
Sil.item_annotation_is_empty ia && PatternMatch.type_is_object t in Typ.item_annotation_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
@ -280,7 +282,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 &&
Sil.item_annotation_is_empty ia && Typ.item_annotation_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
@ -296,17 +298,17 @@ 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 " Sil.pp_item_annotation ia in let pp_ia fmt ia = if ia <> [] then F.fprintf fmt "%a " Typ.pp_item_annotation 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 (Sil.pp_typ_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
F.fprintf fmt "%a%a %s (%a )" F.fprintf fmt "%a%a %s (%a )"
pp_ia ia pp_ia ia
(Sil.pp_typ_full pe_text) ret_type (Typ.pp_full pe_text) ret_type
(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 = { Sil.class_name = s; Sil.parameters = [] } let mk_ann_str s = { Typ.class_name = s; Typ.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

@ -24,8 +24,8 @@ type annotation =
(** Method signature with annotations. *) (** Method signature with annotations. *)
type annotated_signature = type annotated_signature =
{ ret : Sil.item_annotation * Sil.typ; (** Annotated return type. *) { ret : Typ.item_annotation * Typ.t; (** Annotated return type. *)
params: (Mangled.t * Sil.item_annotation * Sil.typ) list } (** Annotated parameters. *) params: (Mangled.t * Typ.item_annotation * 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.
These wrappers have the same name as the original method, every type is Object, and the parameters These wrappers have the same name as the original method, every type is Object, and the parameters
@ -54,67 +54,67 @@ val get_annotated_signature : ProcAttributes.t -> annotated_signature
(** 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] *)
val get_field_type_and_annotation : val get_field_type_and_annotation :
Ident.fieldname -> Sil.typ -> (Sil.typ * Sil.item_annotation) option Ident.fieldname -> Typ.t -> (Typ.t * Typ.item_annotation) option
(** Return the annotations on the declaring class of [java_pname]. *) (** Return the annotations on the declaring class of [java_pname]. *)
val get_declaring_class_annotations : Procname.java -> Tenv.t -> Sil.item_annotation option val get_declaring_class_annotations : Procname.java -> Tenv.t -> Typ.item_annotation option
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 : Sil.annotation -> string -> bool val annot_ends_with : Typ.annotation -> 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 : Sil.item_annotation -> string -> bool val ia_ends_with : Typ.item_annotation -> string -> bool
val ia_contains : Sil.item_annotation -> string -> bool val ia_contains : Typ.item_annotation -> string -> bool
val ia_has_annotation_with : Sil.item_annotation -> (Sil.annotation -> bool) -> bool val ia_has_annotation_with : Typ.item_annotation -> (Typ.annotation -> bool) -> bool
val ia_get_strict : Sil.item_annotation -> Sil.annotation option val ia_get_strict : Typ.item_annotation -> Typ.annotation option
val ia_is_false_on_null : Sil.item_annotation -> bool val ia_is_false_on_null : Typ.item_annotation -> bool
val ia_is_initializer : Sil.item_annotation -> bool val ia_is_initializer : Typ.item_annotation -> 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 : Sil.item_annotation -> bool val ia_is_field_injector_readonly : Typ.item_annotation -> 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 : Sil.item_annotation -> bool val ia_is_field_injector_readwrite : Typ.item_annotation -> bool
val ia_is_mutable : Sil.item_annotation -> bool val ia_is_mutable : Typ.item_annotation -> bool
val ia_is_nonnull : Sil.item_annotation -> bool val ia_is_nonnull : Typ.item_annotation -> bool
val ia_is_nullable : Sil.item_annotation -> bool val ia_is_nullable : Typ.item_annotation -> bool
val ia_is_present : Sil.item_annotation -> bool val ia_is_present : Typ.item_annotation -> bool
val ia_is_true_on_null : Sil.item_annotation -> bool val ia_is_true_on_null : Typ.item_annotation -> bool
val ia_is_verify : Sil.item_annotation -> bool val ia_is_verify : Typ.item_annotation -> bool
val ia_is_expensive : Sil.item_annotation -> bool val ia_is_expensive : Typ.item_annotation -> bool
val ia_is_performance_critical : Sil.item_annotation -> bool val ia_is_performance_critical : Typ.item_annotation -> bool
val ia_is_no_allocation : Sil.item_annotation -> bool val ia_is_no_allocation : Typ.item_annotation -> bool
val ia_is_ignore_allocations : Sil.item_annotation -> bool val ia_is_ignore_allocations : Typ.item_annotation -> bool
val ia_is_suppress_warnings : Sil.item_annotation -> bool val ia_is_suppress_warnings : Typ.item_annotation -> bool
val ia_is_privacy_source : Sil.item_annotation -> bool val ia_is_privacy_source : Typ.item_annotation -> bool
val ia_is_privacy_sink : Sil.item_annotation -> bool val ia_is_privacy_sink : Typ.item_annotation -> bool
val ia_is_integrity_source : Sil.item_annotation -> bool val ia_is_integrity_source : Typ.item_annotation -> bool
val ia_is_integrity_sink : Sil.item_annotation -> bool val ia_is_integrity_sink : Typ.item_annotation -> bool
val ia_is_guarded_by : Sil.item_annotation -> bool val ia_is_guarded_by : Typ.item_annotation -> bool
val ia_iter : (Sil.annotation -> unit) -> Sil.item_annotation -> unit val ia_iter : (Typ.annotation -> unit) -> Typ.item_annotation -> unit
val ma_contains : Sil.method_annotation -> string list -> bool val ma_contains : Typ.method_annotation -> string list -> bool
val ma_has_annotation_with : Sil.method_annotation -> (Sil.annotation -> bool) -> bool val ma_has_annotation_with : Typ.method_annotation -> (Typ.annotation -> bool) -> bool
val ma_iter : (Sil.annotation -> unit) -> Sil.method_annotation -> unit val ma_iter : (Typ.annotation -> unit) -> Typ.method_annotation -> unit
(** 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 -> Sil.method_annotation -> Sil.method_annotation annotation -> Typ.method_annotation -> Typ.method_annotation
(** Add the annotation to the item_annotation. *) (** Add the annotation to the item_annotation. *)
val mk_ia : annotation -> Sil.item_annotation -> Sil.item_annotation val mk_ia : annotation -> Typ.item_annotation -> Typ.item_annotation
val pp_annotated_signature : Procname.t -> Format.formatter -> annotated_signature -> unit val pp_annotated_signature : Procname.t -> Format.formatter -> annotated_signature -> unit

@ -97,10 +97,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.Sil.class_name [Annotations.suppressLint] && IList.mem string_equal a.Typ.class_name [Annotations.suppressLint] &&
IList.mem normalized_equal kind a.Sil.parameters in IList.mem normalized_equal kind a.Typ.parameters in
let is_annotation_suppressed = let is_annotation_suppressed =
string_is_suffix (normalize (drop_prefix kind)) (normalize a.Sil.class_name) in string_is_suffix (normalize (drop_prefix kind)) (normalize a.Typ.class_name) in
is_parameter_suppressed || is_annotation_suppressed in is_parameter_suppressed || is_annotation_suppressed in
@ -204,7 +204,7 @@ let callback_check_write_to_parcel_java
let class_name = let class_name =
Typename.TN_csu (Csu.Class Csu.Java, Mangled.from_string "android.os.Parcelable") in Typename.TN_csu (Csu.Class Csu.Java, Mangled.from_string "android.os.Parcelable") in
match this_type with match this_type with
| Sil.Tptr (Sil.Tstruct struct_typ, _) | Sil.Tstruct struct_typ -> | Typ.Tptr (Typ.Tstruct struct_typ, _) | Typ.Tstruct struct_typ ->
PatternMatch.is_immediate_subtype struct_typ class_name PatternMatch.is_immediate_subtype struct_typ class_name
| _ -> false in | _ -> false in
method_match () && expr_match () && type_match () in method_match () && expr_match () && type_match () in
@ -215,7 +215,7 @@ let callback_check_write_to_parcel_java
proc_desc pname_java ["android.os.Parcel"] in proc_desc pname_java ["android.os.Parcel"] in
let parcel_constructors = function let parcel_constructors = function
| Sil.Tptr (Sil.Tstruct { Sil.def_methods }, _) -> | Typ.Tptr (Typ.Tstruct { Typ.def_methods }, _) ->
IList.filter is_parcel_constructor def_methods IList.filter is_parcel_constructor def_methods
| _ -> [] in | _ -> [] in
@ -319,10 +319,10 @@ let callback_monitor_nullcheck { Callbacks.proc_desc; idenv; proc_name } =
let formals = Cfg.Procdesc.get_formals proc_desc in let formals = Cfg.Procdesc.get_formals proc_desc in
let class_formals = let class_formals =
let is_class_type = function let is_class_type = function
| p, Sil.Tptr _ when Mangled.to_string p = "this" -> | p, Typ.Tptr _ when Mangled.to_string p = "this" ->
false (* no need to null check 'this' *) false (* no need to null check 'this' *)
| _, Sil.Tstruct _ -> true | _, Typ.Tstruct _ -> true
| _, Sil.Tptr (Sil.Tstruct _, _) -> true | _, Typ.Tptr (Typ.Tstruct _, _) -> true
| _ -> false in | _ -> false in
IList.filter is_class_type formals in IList.filter is_class_type formals in
IList.map fst class_formals) in IList.map fst class_formals) in

@ -105,7 +105,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
let kill_ret_ids astate_acc id = let kill_ret_ids astate_acc id =
Domain.kill_copies_with_var (Var.of_id id) astate_acc in Domain.kill_copies_with_var (Var.of_id id) astate_acc in
let kill_actuals_by_ref astate_acc = function let kill_actuals_by_ref astate_acc = function
| (Sil.Lvar pvar, Sil.Tptr _) -> Domain.kill_copies_with_var (Var.of_pvar pvar) astate_acc | (Sil.Lvar pvar, Typ.Tptr _) -> Domain.kill_copies_with_var (Var.of_pvar pvar) astate_acc
| _ -> astate_acc in | _ -> astate_acc in
let astate' = IList.fold_left kill_ret_ids astate ret_ids in let astate' = IList.fold_left kill_ret_ids astate ret_ids in
if !Config.curr_language = Config.Java if !Config.curr_language = Config.Java

@ -27,7 +27,7 @@ let callback_fragment_retains_view_java
let is_on_destroy_view = Procname.java_get_method pname_java = "onDestroyView" in let is_on_destroy_view = Procname.java_get_method pname_java = "onDestroyView" in
(* this is needlessly complicated because field types are Tvars instead of Tstructs *) (* this is needlessly complicated because field types are Tvars instead of Tstructs *)
let fld_typ_is_view = function let fld_typ_is_view = function
| Sil.Tptr (Sil.Tvar tname, _) -> | Typ.Tptr (Typ.Tvar tname, _) ->
begin begin
match Tenv.lookup tenv tname with match Tenv.lookup tenv tname with
| Some struct_typ -> AndroidFramework.is_view tenv struct_typ | Some struct_typ -> AndroidFramework.is_view tenv struct_typ
@ -43,7 +43,7 @@ let callback_fragment_retains_view_java
let class_typename = let class_typename =
Typename.Java.from_string (Procname.java_get_class_name pname_java) in Typename.Java.from_string (Procname.java_get_class_name pname_java) in
match Tenv.lookup tenv class_typename with match Tenv.lookup tenv class_typename with
| Some ({ Sil.struct_name = Some _; instance_fields } as struct_typ) | Some ({ Typ.struct_name = Some _; instance_fields } as struct_typ)
when AndroidFramework.is_fragment tenv struct_typ -> when AndroidFramework.is_fragment tenv struct_typ ->
let declared_view_fields = let declared_view_fields =
IList.filter (is_declared_view_typ class_typename) instance_fields in IList.filter (is_declared_view_typ class_typename) instance_fields in
@ -53,7 +53,7 @@ let callback_fragment_retains_view_java
(fun (fname, fld_typ, _) -> (fun (fname, fld_typ, _) ->
if not (Ident.FieldSet.mem fname fields_nullified) then if not (Ident.FieldSet.mem fname fields_nullified) then
report_error report_error
(Sil.Tstruct struct_typ) fname fld_typ (Typ.Tstruct struct_typ) fname fld_typ
(Procname.Java pname_java) proc_desc) (Procname.Java pname_java) proc_desc)
declared_view_fields declared_view_fields
| _ -> () | _ -> ()

@ -27,7 +27,7 @@ type taint_spec = {
let object_name = Mangled.from_string "java.lang.Object" let object_name = Mangled.from_string "java.lang.Object"
let type_is_object = function let type_is_object = function
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _) -> | Typ.Tptr (Typ.Tstruct { Typ.struct_name = Some name }, _) ->
Mangled.equal name object_name Mangled.equal name object_name
| _ -> false | _ -> false
@ -38,7 +38,7 @@ let java_proc_name_with_class_method pn_java class_with_path method_name =
with _ -> false) with _ -> false)
let get_direct_supers tenv = function let get_direct_supers tenv = function
| { Sil.csu = Csu.Class _; superclasses } -> | { Typ.csu = Csu.Class _; superclasses } ->
IList.map (Tenv.lookup tenv) superclasses IList.map (Tenv.lookup tenv) superclasses
|> IList.flatten_options |> IList.flatten_options
| _ -> | _ ->
@ -61,12 +61,12 @@ let strict_supertype_exists tenv f_typ orig_struct_typ =
get_supers_rec orig_struct_typ get_supers_rec orig_struct_typ
let is_immediate_subtype this_type super_type_name = let is_immediate_subtype this_type super_type_name =
IList.exists (Typename.equal super_type_name) this_type.Sil.superclasses IList.exists (Typename.equal super_type_name) this_type.Typ.superclasses
(** return true if [typ0] <: [typ1] *) (** return true if [typ0] <: [typ1] *)
let is_subtype tenv struct_typ0 struct_typ1 = let is_subtype tenv struct_typ0 struct_typ1 =
Sil.struct_typ_equal struct_typ0 struct_typ1 || Typ.struct_typ_equal struct_typ0 struct_typ1 ||
strict_supertype_exists tenv (Sil.struct_typ_equal struct_typ1) struct_typ0 strict_supertype_exists tenv (Typ.struct_typ_equal struct_typ1) struct_typ0
let is_subtype_of_str tenv cn1 classname_str = let is_subtype_of_str tenv cn1 classname_str =
let typename = Typename.Java.from_string classname_str in let typename = Typename.Java.from_string classname_str in
@ -81,61 +81,61 @@ let get_this_type proc_attributes = match proc_attributes.ProcAttributes.formals
| _ -> None | _ -> None
let type_get_direct_supertypes = function let type_get_direct_supertypes = function
| Sil.Tptr (Tstruct { superclasses }, _) | Typ.Tptr (Tstruct { superclasses }, _)
| Sil.Tstruct { superclasses } -> | Typ.Tstruct { superclasses } ->
superclasses superclasses
| _ -> | _ ->
[] []
let type_get_class_name t = match t with let type_get_class_name t = match t with
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some cn }, _) -> | Typ.Tptr (Typ.Tstruct { Typ.struct_name = Some cn }, _) ->
Some cn Some cn
| Sil.Tptr (Sil.Tvar (Typename.TN_csu (Csu.Class _, cn)), _) -> | Typ.Tptr (Typ.Tvar (Typename.TN_csu (Csu.Class _, cn)), _) ->
Some cn Some cn
| _ -> None | _ -> None
let type_get_annotation let type_get_annotation
(t: Sil.typ): Sil.item_annotation option = (t: Typ.t): Typ.item_annotation option =
match t with match t with
| Sil.Tptr (Sil.Tstruct { Sil.struct_annotations }, _) | Typ.Tptr (Typ.Tstruct { Typ.struct_annotations }, _)
| Sil.Tstruct { Sil.struct_annotations } -> | Typ.Tstruct { Typ.struct_annotations } ->
Some struct_annotations Some struct_annotations
| _ -> None | _ -> None
let type_has_class_name t name = let type_has_class_name t name =
type_get_class_name t = Some name type_get_class_name t = Some name
let type_has_direct_supertype (typ : Sil.typ) (class_name : Typename.t) = let type_has_direct_supertype (typ : Typ.t) (class_name : Typename.t) =
IList.exists (fun cn -> Typename.equal cn class_name) (type_get_direct_supertypes typ) IList.exists (fun cn -> Typename.equal cn class_name) (type_get_direct_supertypes typ)
let type_has_supertype let type_has_supertype
(tenv: Tenv.t) (tenv: Tenv.t)
(typ: Sil.typ) (typ: Typ.t)
(class_name: Typename.t): bool = (class_name: Typename.t): bool =
let rec has_supertype typ visited = let rec has_supertype typ visited =
if Sil.TypSet.mem typ visited then if Typ.Set.mem typ visited then
false false
else else
begin begin
match Tenv.expand_type tenv typ with match Tenv.expand_type tenv typ with
| Sil.Tptr (Sil.Tstruct { Sil.superclasses }, _) | Typ.Tptr (Typ.Tstruct { Typ.superclasses }, _)
| Sil.Tstruct { Sil.superclasses } -> | Typ.Tstruct { Typ.superclasses } ->
let match_supertype cn = let match_supertype cn =
let match_name () = Typename.equal cn class_name in let match_name () = Typename.equal cn class_name in
let has_indirect_supertype () = let has_indirect_supertype () =
match Tenv.lookup tenv cn with match Tenv.lookup tenv cn with
| Some supertype -> | Some supertype ->
has_supertype (Sil.Tstruct supertype) (Sil.TypSet.add typ visited) has_supertype (Typ.Tstruct supertype) (Typ.Set.add typ visited)
| None -> false in | None -> false in
(match_name () || has_indirect_supertype ()) in (match_name () || has_indirect_supertype ()) in
IList.exists match_supertype superclasses IList.exists match_supertype superclasses
| _ -> false | _ -> false
end in end in
has_supertype typ Sil.TypSet.empty has_supertype typ Typ.Set.empty
let type_is_nested_in_type t n = match t with let type_is_nested_in_type t n = match t with
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _) -> | Typ.Tptr (Typ.Tstruct { Typ.struct_name = Some name }, _) ->
string_is_prefix (Mangled.to_string n ^ "$") (Mangled.to_string name) string_is_prefix (Mangled.to_string n ^ "$") (Mangled.to_string name)
| _ -> false | _ -> false
@ -144,18 +144,18 @@ let type_is_nested_in_direct_supertype t n =
IList.exists (is_nested_in n) (type_get_direct_supertypes t) IList.exists (is_nested_in n) (type_get_direct_supertypes t)
let rec get_type_name = function let rec get_type_name = function
| Sil.Tstruct { Sil.struct_name = Some name } -> | Typ.Tstruct { Typ.struct_name = Some name } ->
Mangled.to_string name Mangled.to_string name
| Sil.Tptr (t, _) -> get_type_name t | Typ.Tptr (t, _) -> get_type_name t
| Sil.Tvar tn -> Typename.name tn | Typ.Tvar tn -> Typename.name tn
| _ -> "_" | _ -> "_"
let get_field_type_name let get_field_type_name
(typ: Sil.typ) (typ: Typ.t)
(fieldname: Ident.fieldname): string option = (fieldname: Ident.fieldname): string option =
match typ with match typ with
| Sil.Tstruct { Sil.instance_fields } | Typ.Tstruct { Typ.instance_fields }
| Sil.Tptr (Sil.Tstruct { Sil.instance_fields }, _) -> ( | Typ.Tptr (Typ.Tstruct { Typ.instance_fields }, _) -> (
try try
let _, ft, _ = IList.find let _, ft, _ = IList.find
(function | (fn, _, _) -> Ident.fieldname_equal fn fieldname) (function | (fn, _, _) -> Ident.fieldname_equal fn fieldname)
@ -265,10 +265,10 @@ let get_java_method_call_formal_signature = function
let type_is_class = function let type_is_class = function
| Sil.Tptr (Sil.Tstruct _, _) -> true | Typ.Tptr (Typ.Tstruct _, _) -> true
| Sil.Tptr (Sil.Tvar _, _) -> true | Typ.Tptr (Typ.Tvar _, _) -> true
| Sil.Tptr (Sil.Tarray _, _) -> true | Typ.Tptr (Typ.Tarray _, _) -> true
| Sil.Tstruct _ -> true | Typ.Tstruct _ -> true
| _ -> false | _ -> false
let initializer_classes = let initializer_classes =
@ -292,7 +292,7 @@ let initializer_methods = [
(** Check if the type has in its supertypes from the initializer_classes list. *) (** Check if the type has in its supertypes from the initializer_classes list. *)
let type_has_initializer let type_has_initializer
(tenv: Tenv.t) (tenv: Tenv.t)
(t: Sil.typ): bool = (t: Typ.t): bool =
let check_candidate class_name = type_has_supertype tenv t class_name in let check_candidate class_name = type_has_supertype tenv t class_name in
IList.exists check_candidate initializer_classes IList.exists check_candidate initializer_classes
@ -357,7 +357,7 @@ let proc_iter_overridden_methods f tenv proc_name =
let super_proc_name = let super_proc_name =
Procname.replace_class proc_name (Typename.name super_class_name) in Procname.replace_class proc_name (Typename.name super_class_name) in
match Tenv.lookup tenv super_class_name with match Tenv.lookup tenv super_class_name with
| Some ({ Sil.def_methods }) -> | Some ({ Typ.def_methods }) ->
let is_override pname = let is_override pname =
Procname.equal pname super_proc_name && Procname.equal pname super_proc_name &&
not (Procname.is_constructor pname) in not (Procname.is_constructor pname) in
@ -377,7 +377,7 @@ let proc_iter_overridden_methods f tenv proc_name =
| Some curr_struct_typ -> | Some curr_struct_typ ->
IList.iter IList.iter
(do_super_type tenv) (do_super_type tenv)
(type_get_direct_supertypes (Sil.Tstruct curr_struct_typ)) (type_get_direct_supertypes (Typ.Tstruct curr_struct_typ))
| None -> | None ->
()) ())
| _ -> | _ ->

@ -30,10 +30,10 @@ val get_java_method_call_formal_signature :
Sil.instr -> (string * string * string list * string) option Sil.instr -> (string * string * string list * string) option
(** Get the this type of a procedure *) (** Get the this type of a procedure *)
val get_this_type : ProcAttributes.t -> Sil.typ option val get_this_type : ProcAttributes.t -> Typ.t option
(** Get the name of a type *) (** Get the name of a type *)
val get_type_name : Sil.typ -> string val get_type_name : Typ.t -> string
(** Get the type names of a variable argument *) (** Get the type names of a variable argument *)
val get_vararg_type_names : Cfg.Node.t -> Pvar.t -> string list val get_vararg_type_names : Cfg.Node.t -> Pvar.t -> string list
@ -51,19 +51,19 @@ val is_getter : Procname.java -> bool
val is_setter : Procname.java -> bool val is_setter : Procname.java -> bool
(** Is the type a direct subtype of the typename? *) (** Is the type a direct subtype of the typename? *)
val is_immediate_subtype : Sil.struct_typ -> Typename.t -> bool val is_immediate_subtype : Typ.struct_typ -> Typename.t -> bool
(** Is the type a transitive subtype of the typename? *) (** Is the type a transitive subtype of the typename? *)
val is_subtype : Tenv.t -> Sil.struct_typ -> Sil.struct_typ -> bool val is_subtype : Tenv.t -> Typ.struct_typ -> Typ.struct_typ -> bool
(** Resolve [typ_str] in [tenv], then check [typ] <: [typ_str] *) (** Resolve [typ_str] in [tenv], then check [typ] <: [typ_str] *)
val is_subtype_of_str : Tenv.t -> Typename.t -> string -> bool val is_subtype_of_str : Tenv.t -> Typename.t -> string -> bool
(** get the superclasses of [typ]. does not include [typ] itself *) (** get the superclasses of [typ]. does not include [typ] itself *)
val strict_supertype_iter : Tenv.t -> (Sil.struct_typ -> unit) -> Sil.struct_typ -> unit val strict_supertype_iter : Tenv.t -> (Typ.struct_typ -> unit) -> Typ.struct_typ -> unit
(** Return [true] if [f_typ] evaluates to true on a strict supertype of [orig_struct_typ] *) (** Return [true] if [f_typ] evaluates to true on a strict supertype of [orig_struct_typ] *)
val strict_supertype_exists : Tenv.t -> (Sil.struct_typ -> bool) -> Sil.struct_typ -> bool val strict_supertype_exists : Tenv.t -> (Typ.struct_typ -> bool) -> Typ.struct_typ -> bool
(** Get the name of the type of a constant *) (** Get the name of the type of a constant *)
val java_get_const_type_name : Sil.const -> string val java_get_const_type_name : Sil.const -> string
@ -84,27 +84,27 @@ 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 : Sil.typ -> Sil.item_annotation option val type_get_annotation : Typ.t -> Typ.item_annotation option
(** Get the class name of the type *) (** Get the class name of the type *)
val type_get_class_name : Sil.typ -> Mangled.t option val type_get_class_name : Typ.t -> Mangled.t option
val type_get_direct_supertypes : Sil.typ -> Typename.t list val type_get_direct_supertypes : Typ.t -> Typename.t list
(** Is the type a class with the given name *) (** Is the type a class with the given name *)
val type_has_class_name : Sil.typ -> Mangled.t -> bool val type_has_class_name : Typ.t -> Mangled.t -> bool
val type_has_direct_supertype : Sil.typ -> Typename.t -> bool val type_has_direct_supertype : Typ.t -> Typename.t -> bool
(** Is the type a class type *) (** Is the type a class type *)
val type_is_class : Sil.typ -> bool val type_is_class : Typ.t -> bool
val type_is_nested_in_direct_supertype : Sil.typ -> Typename.t -> bool val type_is_nested_in_direct_supertype : Typ.t -> Typename.t -> bool
val type_is_nested_in_type : Sil.typ -> Mangled.t -> bool val type_is_nested_in_type : Typ.t -> Mangled.t -> bool
(** Is the type java.lang.Object *) (** Is the type java.lang.Object *)
val type_is_object : Sil.typ -> bool val type_is_object : Typ.t -> bool
(** return the set of instance fields that are assigned to a null literal in [procdesc] *) (** return the set of instance fields that are assigned to a null literal in [procdesc] *)
val get_fields_nullified : Cfg.Procdesc.t -> Ident.FieldSet.t val get_fields_nullified : Cfg.Procdesc.t -> Ident.FieldSet.t

@ -85,7 +85,7 @@ let format_type_matches_given_type
(* The format string and the nvar for the fixed arguments and the nvar of the varargs array *) (* The format string and the nvar for the fixed arguments and the nvar of the varargs array *)
let format_arguments let format_arguments
(printf: printf_signature) (printf: printf_signature)
(args: (Sil.exp * Sil.typ) list): (string option * (Sil.exp list) * (Sil.exp option)) = (args: (Sil.exp * Typ.t) list): (string option * (Sil.exp list) * (Sil.exp option)) =
let format_string = match IList.nth args printf.format_pos with let format_string = match IList.nth args printf.format_pos with
| Sil.Const (Sil.Cstr fmt), _ -> Some fmt | Sil.Const (Sil.Cstr fmt), _ -> Some fmt

@ -29,7 +29,7 @@ let assignment_arc_mode e1 typ e2 loc rhs_owning_method is_e1_decl =
let bi_retain = Sil.Const (Sil.Cfun procname) in let bi_retain = Sil.Const (Sil.Cfun procname) in
Sil.Call([], bi_retain, [(e, t)], loc, Sil.cf_default) in Sil.Call([], bi_retain, [(e, t)], loc, Sil.cf_default) in
match typ with match typ with
| Sil.Tptr (_, Sil.Pk_pointer) when not rhs_owning_method && not is_e1_decl -> | Typ.Tptr (_, Typ.Pk_pointer) when not rhs_owning_method && not is_e1_decl ->
(* for __strong e1 = e2 the semantics is*) (* for __strong e1 = e2 the semantics is*)
(* retain(e2); tmp=e1; e1=e2; release(tmp); *) (* retain(e2); tmp=e1; e1=e2; release(tmp); *)
let retain = mk_call retain_pname e2 typ in let retain = mk_call retain_pname e2 typ in
@ -37,15 +37,15 @@ let assignment_arc_mode e1 typ e2 loc rhs_owning_method is_e1_decl =
let tmp_assign = Sil.Letderef(id, e1, typ, loc) in let tmp_assign = Sil.Letderef(id, e1, typ, loc) in
let release = mk_call release_pname (Sil.Var id) typ in let release = mk_call release_pname (Sil.Var id) typ in
(e1,[retain; tmp_assign; assign; release]) (e1,[retain; tmp_assign; assign; release])
| Sil.Tptr (_, Sil.Pk_pointer) when not rhs_owning_method && is_e1_decl -> | Typ.Tptr (_, Typ.Pk_pointer) when not rhs_owning_method && is_e1_decl ->
(* for A __strong *e1 = e2 the semantics is*) (* for A __strong *e1 = e2 the semantics is*)
(* retain(e2); e1=e2; *) (* retain(e2); e1=e2; *)
let retain = mk_call retain_pname e2 typ in let retain = mk_call retain_pname e2 typ in
(e1,[retain; assign]) (e1,[retain; assign])
| Sil.Tptr (_, Sil.Pk_objc_weak) | Typ.Tptr (_, Typ.Pk_objc_weak)
| Sil.Tptr (_, Sil.Pk_objc_unsafe_unretained) -> | Typ.Tptr (_, Typ.Pk_objc_unsafe_unretained) ->
(e1, [assign]) (e1, [assign])
| Sil.Tptr (_, Sil.Pk_objc_autoreleasing) -> | Typ.Tptr (_, Typ.Pk_objc_autoreleasing) ->
(* for __autoreleasing e1 = e2 the semantics is*) (* for __autoreleasing e1 = e2 the semantics is*)
(* retain(e2); autorelease(e2); e1=e2; *) (* retain(e2); autorelease(e2); e1=e2; *)
let retain = mk_call retain_pname e2 typ in let retain = mk_call retain_pname e2 typ in

@ -14,13 +14,13 @@ open! Utils
val bin_op_to_string : Clang_ast_t.binary_operator_info -> string val bin_op_to_string : Clang_ast_t.binary_operator_info -> string
val binary_operation_instruction : val binary_operation_instruction :
CContext.t -> Clang_ast_t.binary_operator_info -> Sil.exp -> Sil.typ -> Sil.exp -> CContext.t -> Clang_ast_t.binary_operator_info -> Sil.exp -> Typ.t -> Sil.exp ->
Location.t -> bool -> Sil.exp * Sil.instr list Location.t -> bool -> Sil.exp * Sil.instr list
val unary_operation_instruction : val unary_operation_instruction :
Clang_ast_t.unary_operator_info -> Sil.exp -> Sil.typ -> Location.t -> Sil.exp * Sil.instr list Clang_ast_t.unary_operator_info -> Sil.exp -> Typ.t -> Location.t -> Sil.exp * Sil.instr list
val assignment_arc_mode : val assignment_arc_mode :
Sil.exp -> Sil.typ -> Sil.exp -> Location.t -> bool -> bool -> Sil.exp * Sil.instr list Sil.exp -> Typ.t -> Sil.exp -> Location.t -> bool -> bool -> Sil.exp * Sil.instr list
val sil_const_plus_one : Sil.exp -> Sil.exp val sil_const_plus_one : Sil.exp -> Sil.exp

@ -31,10 +31,10 @@ type t =
procdesc : Cfg.Procdesc.t; procdesc : Cfg.Procdesc.t;
is_objc_method : bool; is_objc_method : bool;
curr_class: curr_class; curr_class: curr_class;
return_param_typ : Sil.typ option; return_param_typ : Typ.t option;
is_callee_expression : bool; is_callee_expression : bool;
outer_context : t option; (* in case of objc blocks, the context of the method containing the block *) outer_context : t option; (* in case of objc blocks, the context of the method containing the block *)
mutable blocks_static_vars : ((Pvar.t * Sil.typ) list) Procname.Map.t; mutable blocks_static_vars : ((Pvar.t * Typ.t) list) Procname.Map.t;
label_map : str_node_map; label_map : str_node_map;
} }
@ -123,7 +123,7 @@ let curr_class_hash curr_class =
let create_curr_class tenv class_name ck = let create_curr_class tenv class_name ck =
let class_tn_name = Typename.TN_csu (Csu.Class ck, (Mangled.from_string class_name)) in let class_tn_name = Typename.TN_csu (Csu.Class ck, (Mangled.from_string class_name)) in
match Tenv.lookup tenv class_tn_name with match Tenv.lookup tenv class_tn_name with
| Some { Sil.superclasses } -> | Some { Typ.superclasses } ->
(let superclasses_names = IList.map Typename.name superclasses in (let superclasses_names = IList.map Typename.name superclasses in
match superclasses_names with match superclasses_names with
| superclass:: protocols -> | superclass:: protocols ->

@ -29,10 +29,10 @@ type t =
procdesc : Cfg.Procdesc.t; procdesc : Cfg.Procdesc.t;
is_objc_method : bool; is_objc_method : bool;
curr_class: curr_class; curr_class: curr_class;
return_param_typ : Sil.typ option; return_param_typ : Typ.t option;
is_callee_expression : bool; is_callee_expression : bool;
outer_context : t option; (* in case of objc blocks, the context of the method containing the block *) outer_context : t option; (* in case of objc blocks, the context of the method containing the block *)
mutable blocks_static_vars : ((Pvar.t * Sil.typ) list) Procname.Map.t; mutable blocks_static_vars : ((Pvar.t * Typ.t) list) Procname.Map.t;
label_map : str_node_map; label_map : str_node_map;
} }
@ -59,13 +59,13 @@ val is_objc_method : t -> bool
val get_tenv : t -> Tenv.t val get_tenv : t -> Tenv.t
val create_context : Tenv.t -> Cg.t -> Cfg.cfg -> Cfg.Procdesc.t -> val create_context : Tenv.t -> Cg.t -> Cfg.cfg -> Cfg.Procdesc.t ->
curr_class -> Sil.typ option -> bool -> t option -> t curr_class -> Typ.t option -> bool -> t option -> t
val create_curr_class : Tenv.t -> string -> Csu.class_kind -> curr_class val create_curr_class : Tenv.t -> string -> Csu.class_kind -> curr_class
val add_block_static_var : t -> Procname.t -> (Pvar.t * Sil.typ) -> unit val add_block_static_var : t -> Procname.t -> (Pvar.t * Typ.t) -> unit
val static_vars_for_block : t -> Procname.t -> (Pvar.t * Sil.typ) list val static_vars_for_block : t -> Procname.t -> (Pvar.t * Typ.t) list
val is_objc_instance : t -> bool val is_objc_instance : t -> bool

@ -46,7 +46,7 @@ let enum_decl decl =
match decl with match decl with
| EnumDecl (_, _, _, type_ptr, decl_list, _, _) -> | EnumDecl (_, _, _, type_ptr, decl_list, _, _) ->
add_enum_constants_to_map (IList.rev decl_list); add_enum_constants_to_map (IList.rev decl_list);
let sil_type = Sil.Tint Sil.IInt in let sil_type = Typ.Tint Typ.IInt in
Ast_utils.update_sil_types_map type_ptr sil_type; Ast_utils.update_sil_types_map type_ptr sil_type;
sil_type sil_type

@ -12,4 +12,4 @@ open! Utils
(** Translate an enumeration declaration by adding it to the tenv and *) (** Translate an enumeration declaration by adding it to the tenv and *)
(** translating the code and adding it to a fake procdesc *) (** translating the code and adding it to a fake procdesc *)
val enum_decl : Clang_ast_t.decl -> Sil.typ val enum_decl : Clang_ast_t.decl -> Typ.t

@ -15,16 +15,16 @@ open CFrontend_utils
module L = Logging module L = Logging
type field_type = Ident.fieldname * Sil.typ * (Sil.annotation * bool) list type field_type = Ident.fieldname * Typ.t * (Typ.annotation * 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);
match Tenv.lookup tenv super_class with match Tenv.lookup tenv super_class with
| None -> [] | None -> []
| Some { Sil.instance_fields; superclasses = super_class :: _ } -> | Some { Typ.instance_fields; superclasses = super_class :: _ } ->
let sc_fields = get_fields_super_classes tenv super_class in let sc_fields = get_fields_super_classes tenv super_class in
General_utils.append_no_duplicates_fields instance_fields sc_fields General_utils.append_no_duplicates_fields instance_fields sc_fields
| Some { Sil.instance_fields } -> instance_fields | Some { Typ.instance_fields } -> instance_fields
let fields_superclass tenv interface_decl_info ck = let fields_superclass tenv interface_decl_info ck =
match interface_decl_info.Clang_ast_t.otdi_super with match interface_decl_info.Clang_ast_t.otdi_super with
@ -40,16 +40,16 @@ let build_sil_field type_ptr_to_sil_type tenv field_name type_ptr prop_attribute
let prop_atts = IList.map Clang_ast_j.string_of_property_attribute prop_attributes in let prop_atts = IList.map Clang_ast_j.string_of_property_attribute prop_attributes in
let annotation_from_type t = let annotation_from_type t =
match t with match t with
| Sil.Tptr (_, Sil.Pk_objc_weak) -> [Config.weak] | Typ.Tptr (_, Typ.Pk_objc_weak) -> [Config.weak]
| Sil.Tptr (_, Sil.Pk_objc_unsafe_unretained) -> [Config.unsafe_unret] | Typ.Tptr (_, Typ.Pk_objc_unsafe_unretained) -> [Config.unsafe_unret]
| _ -> [] in | _ -> [] in
let fname = General_utils.mk_class_field_name field_name in let fname = General_utils.mk_class_field_name field_name in
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
| [] -> | [] ->
[({ Sil.class_name = Config.ivar_attributes; Sil.parameters = annotation_from_type typ }, true)] [({ Typ.class_name = Config.ivar_attributes; parameters = annotation_from_type typ }, true)]
| _ -> | _ ->
[({ Sil.class_name = Config.property_attributes; Sil.parameters = prop_atts }, true)] in [({ Typ.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 *)
@ -79,12 +79,12 @@ let add_missing_fields tenv class_name ck fields =
let mang_name = Mangled.from_string class_name in let mang_name = Mangled.from_string class_name in
let class_tn_name = Typename.TN_csu (Csu.Class ck, mang_name) in let class_tn_name = Typename.TN_csu (Csu.Class ck, mang_name) in
match Tenv.lookup tenv class_tn_name with match Tenv.lookup tenv class_tn_name with
| Some ({ Sil.instance_fields } as struct_typ) -> | Some ({ Typ.instance_fields } as struct_typ) ->
let new_fields = General_utils.append_no_duplicates_fields instance_fields fields in let new_fields = General_utils.append_no_duplicates_fields instance_fields fields in
let class_type_info = let class_type_info =
{ {
struct_typ with struct_typ with
Sil.instance_fields = new_fields; Typ.instance_fields = new_fields;
static_fields = []; static_fields = [];
csu = Csu.Class ck; csu = Csu.Class ck;
struct_name = Some mang_name; struct_name = Some mang_name;
@ -96,8 +96,8 @@ let add_missing_fields tenv class_name ck fields =
(* checks if ivar is defined among a set of fields and if it is atomic *) (* checks if ivar is defined among a set of fields and if it is atomic *)
let is_ivar_atomic ivar fields = let is_ivar_atomic ivar fields =
let do_one_annot a = let do_one_annot a =
(a.Sil.class_name = Config.property_attributes) && (a.Typ.class_name = Config.property_attributes) &&
IList.exists (fun p -> p = CFrontend_config.atomic_att) a.Sil.parameters in IList.exists (fun p -> p = CFrontend_config.atomic_att) a.Typ.parameters in
let has_atomic_annot ans = let has_atomic_annot ans =
IList.exists (fun (a, _) -> do_one_annot a) ans in IList.exists (fun (a, _) -> do_one_annot a) ans in
try try

@ -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 * Sil.typ * (Sil.annotation * bool) list type field_type = Ident.fieldname * Typ.t * (Typ.annotation * 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
@ -25,4 +25,4 @@ val build_sil_field : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.na
val add_missing_fields : Tenv.t -> string -> Csu.class_kind -> field_type list -> unit val add_missing_fields : Tenv.t -> string -> Csu.class_kind -> field_type list -> unit
val is_ivar_atomic : Ident.fieldname -> Sil.struct_fields -> bool val is_ivar_atomic : Ident.fieldname -> Typ.struct_fields -> bool

@ -191,7 +191,7 @@ let direct_atomic_property_access_warning context stmt_info ivar_name =
| _ -> Ident.create_fieldname (Mangled.from_string "") 0, "" in | _ -> Ident.create_fieldname (Mangled.from_string "") 0, "" in
let tname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string cname) in let tname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string cname) in
let condition = match Tenv.lookup tenv tname with let condition = match Tenv.lookup tenv tname with
| Some { Sil.instance_fields; static_fields } -> | Some { Typ.instance_fields; static_fields } ->
(* We give the warning when: (* We give the warning when:
(1) the property has the atomic attribute and (1) the property has the atomic attribute and
(2) the access of the ivar is not in a getter or setter method. (2) the access of the ivar is not in a getter or setter method.
@ -218,7 +218,7 @@ let direct_atomic_property_access_warning context stmt_info ivar_name =
let captured_cxx_ref_in_objc_block_warning stmt_info captured_vars = let captured_cxx_ref_in_objc_block_warning stmt_info captured_vars =
let is_cxx_ref (_, typ) = let is_cxx_ref (_, typ) =
match typ with match typ with
| Sil.Tptr(_, Sil.Pk_reference) -> true | Typ.Tptr(_, Typ.Pk_reference) -> true
| _ -> false in | _ -> false in
let capt_refs = IList.filter is_cxx_ref captured_vars in let capt_refs = IList.filter is_cxx_ref captured_vars in
let pvar_descs = let pvar_descs =

@ -34,7 +34,7 @@ val direct_atomic_property_access_warning :
(* CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK: C++ references (* CXX_REFERENCE_CAPTURED_IN_OBJC_BLOCK: C++ references
should not be captured in blocks. *) should not be captured in blocks. *)
val captured_cxx_ref_in_objc_block_warning : Clang_ast_t.stmt_info -> (Pvar.t * Sil.typ) list -> val captured_cxx_ref_in_objc_block_warning : Clang_ast_t.stmt_info -> (Pvar.t * Typ.t) list ->
warning_desc option warning_desc option
(* REGISTERED_OBSERVER_BEING_DEALLOCATED: an object is registered in a notification center (* REGISTERED_OBSERVER_BEING_DEALLOCATED: an object is registered in a notification center

@ -131,7 +131,7 @@ val pointer_type_index : Clang_ast_t.c_type Clang_ast_main.PointerMap.t ref
(** Map from type pointers (clang pointers and types created later by frontend) to sil types (** Map from type pointers (clang pointers and types created later by frontend) to sil types
Populated during frontend execution when new type is found *) Populated during frontend execution when new type is found *)
val sil_types_map : (Sil.typ Clang_ast_types.TypePointerMap.t) ref val sil_types_map : (Typ.t Clang_ast_types.TypePointerMap.t) ref
(** Map from enum constants pointers to their predecesor and their sil value *) (** Map from enum constants pointers to their predecesor and their sil value *)
val enum_map : (Clang_ast_t.pointer option * Sil.exp option) Clang_ast_main.PointerMap.t ref val enum_map : (Clang_ast_t.pointer option * Sil.exp option) Clang_ast_main.PointerMap.t ref

@ -27,12 +27,12 @@ struct
let annotation_to_string (annotation, _) = let annotation_to_string (annotation, _) =
"< " ^ annotation.Sil.class_name ^ " : " ^ "< " ^ annotation.Typ.class_name ^ " : " ^
(IList.to_string (fun x -> x) annotation.Sil.parameters) ^ " >" (IList.to_string (fun x -> x) annotation.Typ.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) ^ " " ^
(Sil.typ_to_string typ) ^ (IList.to_string annotation_to_string annotation) (Typ.to_string typ) ^ (IList.to_string annotation_to_string annotation)
let log_stats fmt = let log_stats fmt =
let pp = let pp =
@ -46,7 +46,7 @@ struct
| 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) ^ " " ^
(Sil.item_annotation_to_string struct_t.struct_annotations) ^ "\n" ^ (Typ.item_annotation_to_string struct_t.struct_annotations) ^ "\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.superclasses) ^ "\t" ^ (Typename.to_string tn) ^ "\n") struct_t.superclasses) ^
"---> methods " ^ "---> methods " ^
@ -64,15 +64,15 @@ struct
(Typename.to_string typname)^"\n"^ (Typename.to_string typname)^"\n"^
"\t---> fields "^(IList.to_string (fun (fieldname, typ, _) -> "\t---> fields "^(IList.to_string (fun (fieldname, typ, _) ->
match typ with match typ with
| Sil.Tvar tname -> "tvar"^(Typename.to_string tname) | Typ.Tvar tname -> "tvar"^(Typename.to_string tname)
| Sil.Tstruct _ | _ -> | Typ.Tstruct _ | _ ->
"\t struct "^(Ident.fieldname_to_string fieldname)^" "^ "\t struct "^(Ident.fieldname_to_string fieldname)^" "^
(Sil.typ_to_string typ)^"\n") struct_t.instance_fields (Typ.to_string typ)^"\n") struct_t.instance_fields
) )
) )
| Typename.TN_typedef typname -> | Typename.TN_typedef typname ->
print_endline print_endline
((Mangled.to_string typname)^"-->"^(Sil.typ_to_string (Sil.Tstruct struct_t))) ((Mangled.to_string typname)^"-->"^(Typ.to_string (Typ.Tstruct struct_t)))
| _ -> () | _ -> ()
) tenv ) tenv
@ -100,7 +100,7 @@ end
module Ast_utils = module Ast_utils =
struct struct
type type_ptr_to_sil_type = Tenv.t -> Clang_ast_t.type_ptr -> Sil.typ type type_ptr_to_sil_type = Tenv.t -> Clang_ast_t.type_ptr -> Typ.t
let string_of_decl decl = let string_of_decl decl =
let name = Clang_ast_proj.get_decl_kind_string decl in let name = Clang_ast_proj.get_decl_kind_string decl in
@ -479,16 +479,16 @@ struct
append_no_duplicates Procname.equal list1 list2 append_no_duplicates Procname.equal list1 list2
let append_no_duplicated_vars list1 list2 = let append_no_duplicated_vars list1 list2 =
let eq (m1, t1) (m2, t2) = (Mangled.equal m1 m2) && (Sil.typ_equal t1 t2) in let eq (m1, t1) (m2, t2) = (Mangled.equal m1 m2) && (Typ.equal t1 t2) in
append_no_duplicates eq list1 list2 append_no_duplicates eq list1 list2
let append_no_duplicateds list1 list2 = let append_no_duplicateds list1 list2 =
let eq (e1, t1) (e2, t2) = (Sil.exp_equal e1 e2) && (Sil.typ_equal t1 t2) in let eq (e1, t1) (e2, t2) = (Sil.exp_equal e1 e2) && (Typ.equal t1 t2) in
append_no_duplicates eq list1 list2 append_no_duplicates eq list1 list2
let append_no_duplicates_annotations list1 list2 = let append_no_duplicates_annotations list1 list2 =
let eq (annot1, _) (annot2, _) = annot1.Sil.class_name = annot2.Sil.class_name in let eq (annot1, _) (annot2, _) = annot1.Typ.class_name = annot2.Typ.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 =
@ -496,7 +496,7 @@ struct
match field_tuple, l with match field_tuple, l with
| (field, typ, annot), ((old_field, old_typ, old_annot) as old_field_tuple :: rest) -> | (field, typ, annot), ((old_field, old_typ, old_annot) as old_field_tuple :: rest) ->
let ret_list, ret_found = replace_field field_tuple rest found in let ret_list, ret_found = replace_field field_tuple rest found in
if Ident.fieldname_equal field old_field && Sil.typ_equal typ old_typ then if Ident.fieldname_equal field old_field && Typ.equal typ old_typ then
let annotations = append_no_duplicates_annotations annot old_annot in let annotations = append_no_duplicates_annotations annot old_annot in
(field, typ, annotations) :: ret_list, true (field, typ, annotations) :: ret_list, true
else old_field_tuple :: ret_list, ret_found else old_field_tuple :: ret_list, ret_found
@ -520,7 +520,7 @@ struct
let sort_fields_tenv tenv = let sort_fields_tenv tenv =
let sort_fields_struct typname st = let sort_fields_struct typname st =
let st' = { st with Sil.instance_fields = (sort_fields st.Sil.instance_fields) } in let st' = { st with Typ.instance_fields = (sort_fields st.Typ.instance_fields) } in
Tenv.add tenv typname st' in Tenv.add tenv typname st' in
Tenv.iter sort_fields_struct tenv Tenv.iter sort_fields_struct tenv

@ -33,7 +33,7 @@ sig
val instrs_to_string : Sil.instr list -> string val instrs_to_string : Sil.instr list -> string
val field_to_string : Ident.fieldname * Sil.typ * Sil.item_annotation -> string val field_to_string : Ident.fieldname * Typ.t * Typ.item_annotation -> string
end end
module Ast_utils : module Ast_utils :
@ -86,7 +86,7 @@ sig
val get_decl_opt_with_decl_ref : Clang_ast_t.decl_ref option -> Clang_ast_t.decl option val get_decl_opt_with_decl_ref : Clang_ast_t.decl_ref option -> Clang_ast_t.decl option
val update_sil_types_map : Clang_ast_t.type_ptr -> Sil.typ -> unit val update_sil_types_map : Clang_ast_t.type_ptr -> Typ.t -> unit
val update_enum_map : Clang_ast_t.pointer -> Sil.exp -> unit val update_enum_map : Clang_ast_t.pointer -> Sil.exp -> unit
@ -120,7 +120,7 @@ sig
val make_qual_name_decl : string list -> string -> Clang_ast_t.named_decl_info val make_qual_name_decl : string list -> string -> Clang_ast_t.named_decl_info
type type_ptr_to_sil_type = Tenv.t -> Clang_ast_t.type_ptr -> Sil.typ type type_ptr_to_sil_type = Tenv.t -> Clang_ast_t.type_ptr -> Typ.t
val add_type_from_decl_ref : type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl_ref option -> val add_type_from_decl_ref : type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl_ref option ->
bool -> unit bool -> unit
@ -156,9 +156,9 @@ sig
val string_from_list : string list -> string val string_from_list : string list -> string
val append_no_duplicates_fields : (Ident.fieldname * Sil.typ * Sil.item_annotation) list -> val append_no_duplicates_fields : (Ident.fieldname * Typ.t * Typ.item_annotation) list ->
(Ident.fieldname * Sil.typ * Sil.item_annotation) list -> (Ident.fieldname * Typ.t * Typ.item_annotation) list ->
(Ident.fieldname * Sil.typ * Sil.item_annotation) list (Ident.fieldname * Typ.t * Typ.item_annotation) 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
@ -166,14 +166,14 @@ sig
val append_no_duplicates_methods : Procname.t list -> Procname.t list -> Procname.t list val append_no_duplicates_methods : Procname.t list -> Procname.t list -> Procname.t list
val append_no_duplicated_vars : val append_no_duplicated_vars :
(Mangled.t * Sil.typ) list -> (Mangled.t * Sil.typ) list -> (Mangled.t * Sil.typ) list (Mangled.t * Typ.t) list -> (Mangled.t * Typ.t) list -> (Mangled.t * Typ.t) list
val append_no_duplicateds : val append_no_duplicateds :
(Sil.exp * Sil.typ) list -> (Sil.exp * Sil.typ) list -> (Sil.exp * Sil.typ) list (Sil.exp * Typ.t) list -> (Sil.exp * Typ.t) list -> (Sil.exp * Typ.t) list
val sort_fields : val sort_fields :
(Ident.fieldname * Sil.typ * Sil.item_annotation) list -> (Ident.fieldname * Typ.t * Typ.item_annotation) list ->
(Ident.fieldname * Sil.typ * Sil.item_annotation) list (Ident.fieldname * Typ.t * Typ.item_annotation) list
val sort_fields_tenv : Tenv.t -> unit val sort_fields_tenv : Tenv.t -> unit

@ -23,7 +23,7 @@ type method_signature = {
language : Config.clang_lang; language : Config.clang_lang;
pointer_to_parent : Clang_ast_t.pointer option; pointer_to_parent : Clang_ast_t.pointer option;
pointer_to_property_opt : Clang_ast_t.pointer option; (* If set then method is a getter/setter *) pointer_to_property_opt : Clang_ast_t.pointer option; (* If set then method is a getter/setter *)
return_param_typ : Sil.typ option; return_param_typ : Typ.t option;
} }
let ms_get_name { name } = let ms_get_name { name } =

@ -37,7 +37,7 @@ val ms_get_pointer_to_parent : method_signature -> Clang_ast_t.pointer option
val ms_get_pointer_to_property_opt : method_signature -> Clang_ast_t.pointer option val ms_get_pointer_to_property_opt : method_signature -> Clang_ast_t.pointer option
val ms_get_return_param_typ : method_signature -> Sil.typ option val ms_get_return_param_typ : method_signature -> Typ.t option
val ms_is_getter : method_signature -> bool val ms_is_getter : method_signature -> bool
@ -46,7 +46,7 @@ val ms_is_setter : method_signature -> bool
val make_ms : Procname.t -> (string * Clang_ast_t.type_ptr) list -> Clang_ast_t.type_ptr val make_ms : Procname.t -> (string * Clang_ast_t.type_ptr) list -> Clang_ast_t.type_ptr
-> Clang_ast_t.attribute list -> Clang_ast_t.source_range -> bool -> ?is_cpp_virtual:bool -> Clang_ast_t.attribute list -> Clang_ast_t.source_range -> bool -> ?is_cpp_virtual:bool
-> Config.clang_lang -> Clang_ast_t.pointer option -> Clang_ast_t.pointer option -> Config.clang_lang -> Clang_ast_t.pointer option -> Clang_ast_t.pointer option
-> Sil.typ option -> method_signature -> Typ.t option -> method_signature
val replace_name_ms : method_signature -> Procname.t -> method_signature val replace_name_ms : method_signature -> Procname.t -> method_signature

@ -64,7 +64,7 @@ let get_class_param function_method_decl_info =
let should_add_return_param return_type ~is_objc_method = let should_add_return_param return_type ~is_objc_method =
match return_type with match return_type with
| Sil.Tstruct _ -> not is_objc_method | Typ.Tstruct _ -> not is_objc_method
| _ -> false | _ -> false
let is_objc_method function_method_decl_info = let is_objc_method function_method_decl_info =
@ -112,7 +112,7 @@ let get_parameters tenv function_method_decl_info =
let name = General_utils.get_var_name_string name_info var_decl_info in let name = General_utils.get_var_name_string name_info var_decl_info in
let param_typ = CTypes_decl.type_ptr_to_sil_type tenv type_ptr in let param_typ = CTypes_decl.type_ptr_to_sil_type tenv type_ptr in
let type_ptr' = match param_typ with let type_ptr' = match param_typ with
| Sil.Tstruct _ when General_utils.is_cpp_translation Config.clang_lang -> | Typ.Tstruct _ when General_utils.is_cpp_translation Config.clang_lang ->
Ast_expressions.create_reference_type type_ptr Ast_expressions.create_reference_type type_ptr
| _ -> type_ptr in | _ -> type_ptr in
(name, type_ptr') (name, type_ptr')
@ -126,7 +126,7 @@ let get_return_type tenv function_method_decl_info =
let return_typ = CTypes_decl.type_ptr_to_sil_type tenv return_type_ptr in let return_typ = CTypes_decl.type_ptr_to_sil_type tenv return_type_ptr in
let is_objc_method = is_objc_method function_method_decl_info in let is_objc_method = is_objc_method function_method_decl_info in
if should_add_return_param return_typ ~is_objc_method then if should_add_return_param return_typ ~is_objc_method then
Ast_expressions.create_void_type, Some (Sil.Tptr (return_typ, Sil.Pk_pointer)) Ast_expressions.create_void_type, Some (Typ.Tptr (return_typ, Typ.Pk_pointer))
else return_type_ptr, None else return_type_ptr, None
let build_method_signature tenv decl_info procname function_method_decl_info let build_method_signature tenv decl_info procname function_method_decl_info
@ -238,7 +238,7 @@ let get_superclass_curr_class_objc context =
let iname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string cname) in let iname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string cname) in
Printing.log_out "Checking for superclass = '%s'\n\n%!" (Typename.to_string iname); Printing.log_out "Checking for superclass = '%s'\n\n%!" (Typename.to_string iname);
match Tenv.lookup (CContext.get_tenv context) iname with match Tenv.lookup (CContext.get_tenv context) iname with
| Some { Sil.superclasses = super_name :: _ } -> | Some { Typ.superclasses = super_name :: _ } ->
Typename.name super_name Typename.name super_name
| _ -> | _ ->
Printing.log_err "NOT FOUND superclass = '%s'\n\n%!" (Typename.to_string iname); Printing.log_err "NOT FOUND superclass = '%s'\n\n%!" (Typename.to_string iname);
@ -277,7 +277,7 @@ let get_class_name_method_call_from_receiver_kind context obj_c_message_expr_inf
(CTypes.classname_of_type sil_type) (CTypes.classname_of_type sil_type)
| `Instance -> | `Instance ->
(match act_params with (match act_params with
| (_, Sil.Tptr(t, _)):: _ | (_, Typ.Tptr(t, _)):: _
| (_, t):: _ -> CTypes.classname_of_type t | (_, t):: _ -> CTypes.classname_of_type t
| _ -> assert false) | _ -> assert false)
| `SuperInstance ->get_superclass_curr_class_objc context | `SuperInstance ->get_superclass_curr_class_objc context
@ -343,10 +343,10 @@ let should_create_procdesc cfg procname defined =
else false else false
| None -> true | None -> true
let sil_method_annotation_of_args args : Sil.method_annotation = let sil_method_annotation_of_args args : Typ.method_annotation =
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 = { Sil.class_name = annot_name; Sil.parameters = [param_name]; } in let annot = { Typ.class_name = annot_name; Typ.parameters = [param_name]; } in
annot, default_visibility in annot, default_visibility in
let arg_to_sil_annot acc (arg_name, type_ptr) = let arg_to_sil_annot acc (arg_name, type_ptr) =
if CFrontend_utils.Ast_utils.is_type_nullable type_ptr then if CFrontend_utils.Ast_utils.is_type_nullable type_ptr then
@ -417,7 +417,7 @@ let create_external_procdesc cfg proc_name is_objc_inst_method type_opt =
(match type_opt with (match type_opt with
| Some (ret_type, arg_types) -> | Some (ret_type, arg_types) ->
ret_type, IList.map (fun typ -> (Mangled.from_string "x", typ)) arg_types ret_type, IList.map (fun typ -> (Mangled.from_string "x", typ)) arg_types
| None -> Sil.Tvoid, []) in | None -> Typ.Tvoid, []) in
let loc = Location.dummy in let loc = Location.dummy in
let proc_attributes = let proc_attributes =
{ (ProcAttributes.default proc_name Config.Clang) with { (ProcAttributes.default proc_name Config.Clang) with

@ -22,18 +22,18 @@ type method_call_type =
| MCNoVirtual | MCNoVirtual
| MCStatic | MCStatic
val should_add_return_param : Sil.typ -> is_objc_method:bool -> bool val should_add_return_param : Typ.t -> is_objc_method:bool -> bool
val create_local_procdesc : Cfg.cfg -> Tenv.t -> CMethod_signature.method_signature -> val create_local_procdesc : Cfg.cfg -> Tenv.t -> CMethod_signature.method_signature ->
Clang_ast_t.stmt list -> (Pvar.t * Sil.typ) list -> bool -> bool Clang_ast_t.stmt list -> (Pvar.t * Typ.t) list -> bool -> bool
val create_external_procdesc : Cfg.cfg -> Procname.t -> bool -> (Sil.typ * Sil.typ list) option -> unit val create_external_procdesc : Cfg.cfg -> Procname.t -> bool -> (Typ.t * Typ.t list) option -> unit
val get_objc_method_data : Clang_ast_t.obj_c_message_expr_info -> val get_objc_method_data : Clang_ast_t.obj_c_message_expr_info ->
(string * Clang_ast_t.pointer option * method_call_type) (string * Clang_ast_t.pointer option * method_call_type)
val get_class_name_method_call_from_receiver_kind : CContext.t -> val get_class_name_method_call_from_receiver_kind : CContext.t ->
Clang_ast_t.obj_c_message_expr_info -> (Sil.exp * Sil.typ) list -> string Clang_ast_t.obj_c_message_expr_info -> (Sil.exp * Typ.t) list -> string
val get_class_name_method_call_from_clang : Tenv.t -> Clang_ast_t.obj_c_message_expr_info -> val get_class_name_method_call_from_clang : Tenv.t -> Clang_ast_t.obj_c_message_expr_info ->
string option string option

@ -9,7 +9,7 @@
open! Utils open! Utils
type block_data = CContext.t * Clang_ast_t.type_ptr * Procname.t * (Pvar.t * Sil.typ) list type block_data = CContext.t * Clang_ast_t.type_ptr * Procname.t * (Pvar.t * Typ.t) list
type instr_type = [ type instr_type = [
| `ClangStmt of Clang_ast_t.stmt | `ClangStmt of Clang_ast_t.stmt

@ -117,7 +117,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 = Sil.item_annotation_empty in let item_annot = Typ.item_annotation_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;
@ -126,7 +126,7 @@ struct
let mblock = Mangled.from_string block_name in let mblock = Mangled.from_string block_name in
let block_struct_typ = let block_struct_typ =
{ {
Sil.instance_fields = fields; Typ.instance_fields = fields;
static_fields = []; static_fields = [];
csu = Csu.Class Csu.Objc; csu = Csu.Class Csu.Objc;
struct_name = Some mblock; struct_name = Some mblock;
@ -134,7 +134,7 @@ struct
def_methods = []; def_methods = [];
struct_annotations = []; struct_annotations = [];
} in } in
let block_type = Sil.Tstruct block_struct_typ in let block_type = Typ.Tstruct block_struct_typ in
let block_name = Typename.TN_csu (Csu.Class Csu.Objc, mblock) in let block_name = Typename.TN_csu (Csu.Class Csu.Objc, mblock) in
Tenv.add tenv block_name block_struct_typ; Tenv.add tenv block_name block_struct_typ;
let trans_res = let trans_res =
@ -145,7 +145,7 @@ struct
| _ -> assert false in | _ -> assert false in
let block_var = Pvar.mk mblock procname in let block_var = Pvar.mk mblock procname in
let declare_block_local = let declare_block_local =
Sil.Declare_locals ([(block_var, Sil.Tptr (block_type, Sil.Pk_pointer))], loc) in Sil.Declare_locals ([(block_var, Typ.Tptr (block_type, Typ.Pk_pointer))], loc) in
let set_instr = Sil.Set (Sil.Lvar block_var, block_type, Sil.Var id_block, loc) in let set_instr = Sil.Set (Sil.Lvar block_var, block_type, Sil.Var id_block, loc) in
let create_field_exp (var, typ) = let create_field_exp (var, typ) =
let id = Ident.create_fresh Ident.knormal in let id = Ident.create_fresh Ident.knormal in
@ -175,7 +175,7 @@ struct
match es with match es with
| [] -> [] | [] -> []
| (Sil.Const (Sil.Cclosure { name; captured_vars}), | (Sil.Const (Sil.Cclosure { name; captured_vars}),
(Sil.Tptr((Sil.Tfun _), _ ) as t)) :: es' -> (Typ.Tptr((Typ.Tfun _), _ ) as t)) :: es' ->
let app = let app =
let function_name = make_function_name t name in let function_name = make_function_name t name in
let args = IList.map (make_arg t) captured_vars in let args = IList.map (make_arg t) captured_vars in
@ -216,7 +216,7 @@ struct
CTypes_decl.objc_class_name_to_sil_type trans_state.context.CContext.tenv class_name in CTypes_decl.objc_class_name_to_sil_type trans_state.context.CContext.tenv class_name in
let expanded_type = CTypes.expand_structured_type trans_state.context.CContext.tenv typ in let expanded_type = CTypes.expand_structured_type trans_state.context.CContext.tenv typ in
{ empty_res_trans with { empty_res_trans with
exps = [(Sil.Sizeof(expanded_type, None, Sil.Subtype.exact), Sil.Tint Sil.IULong)] } exps = [(Sil.Sizeof(expanded_type, None, Sil.Subtype.exact), Typ.Tint Typ.IULong)] }
let add_reference_if_glvalue typ expr_info = let add_reference_if_glvalue typ expr_info =
(* glvalue definition per C++11:*) (* glvalue definition per C++11:*)
@ -225,12 +225,12 @@ struct
| `LValue | `XValue -> true | `LValue | `XValue -> true
| `RValue -> false in | `RValue -> false in
match is_glvalue, typ with match is_glvalue, typ with
| true, Sil.Tptr (_, Sil.Pk_reference) -> | true, Typ.Tptr (_, Typ.Pk_reference) ->
(* reference of reference is not allowed in C++ - it's most likely frontend *) (* reference of reference is not allowed in C++ - it's most likely frontend *)
(* trying to add same reference to same type twice*) (* trying to add same reference to same type twice*)
(* this is hacky and should be fixed (t9838691) *) (* this is hacky and should be fixed (t9838691) *)
typ typ
| true, _ -> Sil.Tptr (typ, Sil.Pk_reference) | true, _ -> Typ.Tptr (typ, Typ.Pk_reference)
| _ -> typ | _ -> typ
(** Execute translation and then possibly adjust the type of the result of translation: (** Execute translation and then possibly adjust the type of the result of translation:
@ -283,12 +283,12 @@ struct
let create_call_instr trans_state return_type function_sil params_sil sil_loc let create_call_instr trans_state return_type function_sil params_sil sil_loc
call_flags ~is_objc_method = call_flags ~is_objc_method =
let ret_id = if (Sil.typ_equal return_type Sil.Tvoid) then [] let ret_id = if (Typ.equal return_type Typ.Tvoid) then []
else [Ident.create_fresh Ident.knormal] in else [Ident.create_fresh Ident.knormal] in
let ret_id', params, initd_exps, ret_exps = let ret_id', params, initd_exps, ret_exps =
(* Assumption: should_add_return_param will return true only for struct types *) (* Assumption: should_add_return_param will return true only for struct types *)
if CMethod_trans.should_add_return_param return_type ~is_objc_method then if CMethod_trans.should_add_return_param return_type ~is_objc_method then
let param_type = Sil.Tptr (return_type, Sil.Pk_pointer) in let param_type = Typ.Tptr (return_type, Typ.Pk_pointer) in
let var_exp = match trans_state.var_exp_typ with let var_exp = match trans_state.var_exp_typ with
| Some (exp, _) -> exp | Some (exp, _) -> exp
| _ -> | _ ->
@ -396,8 +396,8 @@ struct
let typ = CTypes_decl.get_type_from_expr_info expr_info trans_state.context.CContext.tenv in let typ = CTypes_decl.get_type_from_expr_info expr_info trans_state.context.CContext.tenv in
(* constant will be different depending on type *) (* constant will be different depending on type *)
let zero_opt = match typ with let zero_opt = match typ with
| Sil.Tfloat _ | Sil.Tptr _ | Sil.Tint _ -> Some (Sil.zero_value_of_numerical_type typ) | Typ.Tfloat _ | Typ.Tptr _ | Typ.Tint _ -> Some (Sil.zero_value_of_numerical_type typ)
| Sil.Tvoid -> None | Typ.Tvoid -> None
| _ -> Some (Sil.Const (Sil.Cint IntLit.zero)) in | _ -> Some (Sil.Const (Sil.Cint IntLit.zero)) in
match zero_opt with match zero_opt with
| Some zero -> { empty_res_trans with exps = [(zero, typ)] } | Some zero -> { empty_res_trans with exps = [(zero, typ)] }
@ -478,9 +478,9 @@ struct
let _, _, type_ptr = Ast_utils.get_info_from_decl_ref decl_ref in let _, _, type_ptr = Ast_utils.get_info_from_decl_ref decl_ref in
let ast_typ = CTypes_decl.type_ptr_to_sil_type context.tenv type_ptr in let ast_typ = CTypes_decl.type_ptr_to_sil_type context.tenv type_ptr in
let typ = match ast_typ with let typ = match ast_typ with
| Sil.Tstruct _ when decl_ref.Clang_ast_t.dr_kind = `ParmVar -> | Typ.Tstruct _ when decl_ref.Clang_ast_t.dr_kind = `ParmVar ->
if General_utils.is_cpp_translation Config.clang_lang then if General_utils.is_cpp_translation Config.clang_lang then
Sil.Tptr (ast_typ, Sil.Pk_reference) Typ.Tptr (ast_typ, Typ.Pk_reference)
else ast_typ else ast_typ
| _ -> ast_typ in | _ -> ast_typ in
let procname = Cfg.Procdesc.get_proc_name context.procdesc in let procname = Cfg.Procdesc.get_proc_name context.procdesc in
@ -500,7 +500,7 @@ struct
Printing.log_out "\n\n PVAR ='%s'\n\n" (Pvar.to_string pvar); Printing.log_out "\n\n PVAR ='%s'\n\n" (Pvar.to_string pvar);
let res_trans = { empty_res_trans with exps = exps } in let res_trans = { empty_res_trans with exps = exps } in
match typ with match typ with
| Sil.Tptr (_, Sil.Pk_reference) -> | Typ.Tptr (_, Typ.Pk_reference) ->
(* dereference pvar due to the behavior of reference types in clang's AST *) (* dereference pvar due to the behavior of reference types in clang's AST *)
dereference_value_from_result sil_loc res_trans ~strip_pointer:true dereference_value_from_result sil_loc res_trans ~strip_pointer:true
| _ -> res_trans | _ -> res_trans
@ -515,13 +515,13 @@ struct
let (obj_sil, class_typ) = extract_exp_from_list pre_trans_result.exps let (obj_sil, class_typ) = extract_exp_from_list pre_trans_result.exps
"WARNING: in Field dereference we expect to know the object\n" in "WARNING: in Field dereference we expect to know the object\n" in
let is_pointer_typ = match class_typ with let is_pointer_typ = match class_typ with
| Sil.Tptr _ -> true | Typ.Tptr _ -> true
| _ -> false in | _ -> false in
let class_typ = let class_typ =
match class_typ with match class_typ with
| Sil.Tptr (t, _) -> CTypes.expand_structured_type context.CContext.tenv t | Typ.Tptr (t, _) -> CTypes.expand_structured_type context.CContext.tenv t
| t -> t in | t -> t in
Printing.log_out "Type is '%s' @." (Sil.typ_to_string class_typ); Printing.log_out "Type is '%s' @." (Typ.to_string class_typ);
let field_name = General_utils.mk_class_field_name name_info in let field_name = General_utils.mk_class_field_name name_info in
let field_exp = Sil.Lfield (obj_sil, field_name, class_typ) in let field_exp = Sil.Lfield (obj_sil, field_name, class_typ) in
(* In certain cases, there is be no LValueToRValue cast, but backend needs dereference*) (* In certain cases, there is be no LValueToRValue cast, but backend needs dereference*)
@ -570,12 +570,12 @@ struct
| [] -> [], [] | [] -> [], []
(* We need to add a dereference before a method call to find null dereferences when *) (* We need to add a dereference before a method call to find null dereferences when *)
(* calling a method with null *) (* calling a method with null *)
| [(exp, Sil.Tptr (typ, _) )] when decl_kind <> `CXXConstructor -> | [(exp, Typ.Tptr (typ, _) )] when decl_kind <> `CXXConstructor ->
let typ = CTypes.expand_structured_type context.tenv typ in let typ = CTypes.expand_structured_type context.tenv typ in
let extra_instrs, _ = CTrans_utils.dereference_var_sil (exp, typ) sil_loc in let extra_instrs, _ = CTrans_utils.dereference_var_sil (exp, typ) sil_loc in
pre_trans_result.exps, extra_instrs pre_trans_result.exps, extra_instrs
| [(_, Sil.Tptr _ )] -> pre_trans_result.exps, [] | [(_, Typ.Tptr _ )] -> pre_trans_result.exps, []
| [(sil, typ)] -> [(sil, Sil.Tptr (typ, Sil.Pk_reference))], [] | [(sil, typ)] -> [(sil, Typ.Tptr (typ, Typ.Pk_reference))], []
| _ -> assert false | _ -> assert false
) )
else else
@ -855,7 +855,7 @@ struct
NEED TO BE FIXED\n\n"; NEED TO BE FIXED\n\n";
fix_param_exps_mismatch params_stmt params) in fix_param_exps_mismatch params_stmt params) in
let act_params = if is_cf_retain_release then let act_params = if is_cf_retain_release then
(Sil.Const (Sil.Cint IntLit.one), Sil.Tint Sil.IBool) :: act_params (Sil.Const (Sil.Cint IntLit.one), Typ.Tint Typ.IBool) :: act_params
else act_params in else act_params in
match match
CTrans_utils.builtin_trans trans_state_pri sil_loc si function_type callee_pname_opt with CTrans_utils.builtin_trans trans_state_pri sil_loc si function_type callee_pname_opt with
@ -966,8 +966,8 @@ struct
Sil.Lvar pvar, class_type in Sil.Lvar pvar, class_type in
let this_type = let this_type =
match class_type with match class_type with
| Sil.Tptr _ -> class_type | Typ.Tptr _ -> class_type
| _ -> Sil.Tptr (class_type, Sil.Pk_pointer) in | _ -> Typ.Tptr (class_type, Typ.Pk_pointer) in
let this_res_trans = { empty_res_trans with let this_res_trans = { empty_res_trans with
exps = [(var_exp, this_type)]; exps = [(var_exp, this_type)];
initd_exps = [var_exp]; initd_exps = [var_exp];
@ -975,7 +975,7 @@ struct
let res_trans_callee = decl_ref_trans trans_state this_res_trans si decl_ref let res_trans_callee = decl_ref_trans trans_state this_res_trans si decl_ref
~is_constructor_init:false in ~is_constructor_init:false in
let res_trans = cxx_method_construct_call_trans trans_state_pri res_trans_callee let res_trans = cxx_method_construct_call_trans trans_state_pri res_trans_callee
params_stmt si Sil.Tvoid false in params_stmt si Typ.Tvoid false in
{ res_trans with exps = [(var_exp, class_type)] } { res_trans with exps = [(var_exp, class_type)] }
and cxx_destructor_call_trans trans_state si this_res_trans class_type_ptr = and cxx_destructor_call_trans trans_state si this_res_trans class_type_ptr =
@ -983,7 +983,7 @@ struct
let res_trans_callee = destructor_deref_trans trans_state this_res_trans class_type_ptr si in let res_trans_callee = destructor_deref_trans trans_state this_res_trans class_type_ptr si in
let is_cpp_call_virtual = res_trans_callee.is_cpp_call_virtual in let is_cpp_call_virtual = res_trans_callee.is_cpp_call_virtual in
if res_trans_callee.exps <> [] then if res_trans_callee.exps <> [] then
cxx_method_construct_call_trans trans_state_pri res_trans_callee [] si Sil.Tvoid cxx_method_construct_call_trans trans_state_pri res_trans_callee [] si Typ.Tvoid
is_cpp_call_virtual is_cpp_call_virtual
else empty_res_trans else empty_res_trans
@ -1185,7 +1185,7 @@ struct
Printing.log_out " No short-circuit condition\n"; Printing.log_out " No short-circuit condition\n";
let res_trans_cond = let res_trans_cond =
if is_null_stmt cond then { if is_null_stmt cond then {
empty_res_trans with exps = [(Sil.Const (Sil.Cint IntLit.one), (Sil.Tint Sil.IBool))] empty_res_trans with exps = [(Sil.Const (Sil.Cint IntLit.one), (Typ.Tint Typ.IBool))]
} }
(* Assumption: If it's a null_stmt, it is a loop with no bound, so we set condition to 1 *) (* Assumption: If it's a null_stmt, it is a loop with no bound, so we set condition to 1 *)
else else
@ -1584,7 +1584,7 @@ struct
and initListExpr_trans trans_state stmt_info expr_info stmts = and initListExpr_trans trans_state stmt_info expr_info stmts =
let context = trans_state.context in let context = trans_state.context in
let tenv = context.tenv in let tenv = context.tenv in
let is_array typ = match typ with | Sil.Tarray _ -> true | _ -> false in let is_array typ = match typ with | Typ.Tarray _ -> true | _ -> false in
let (var_exp, typ) = let (var_exp, typ) =
match trans_state.var_exp_typ with match trans_state.var_exp_typ with
| Some var_exp_typ -> var_exp_typ | Some var_exp_typ -> var_exp_typ
@ -1871,7 +1871,7 @@ struct
let pvar = Pvar.mk (Mangled.from_string name) procname in let pvar = Pvar.mk (Mangled.from_string name) procname in
let id = Ident.create_fresh Ident.knormal in let id = Ident.create_fresh Ident.knormal in
let instr = Sil.Letderef (id, Sil.Lvar pvar, ret_param_typ, sil_loc) in let instr = Sil.Letderef (id, Sil.Lvar pvar, ret_param_typ, sil_loc) in
let ret_typ = match ret_param_typ with Sil.Tptr (t, _) -> t | _ -> assert false in let ret_typ = match ret_param_typ with Typ.Tptr (t, _) -> t | _ -> assert false in
Sil.Var id, ret_typ, [instr] Sil.Var id, ret_typ, [instr]
| None -> | None ->
Sil.Lvar (Cfg.Procdesc.get_ret_var procdesc), ret_type, [] in Sil.Lvar (Cfg.Procdesc.get_ret_var procdesc), ret_type, [] in
@ -2032,8 +2032,8 @@ struct
and initListExpr_initializers_trans trans_state var_exp n stmts typ is_dyn_array stmt_info = and initListExpr_initializers_trans trans_state var_exp n stmts typ is_dyn_array stmt_info =
let (var_exp_inside, typ_inside) = match typ with let (var_exp_inside, typ_inside) = match typ with
| Sil.Tarray (t, _) | Typ.Tarray (t, _)
| Sil.Tptr (t, _) when Sil.is_array_of_cpp_class typ || is_dyn_array -> | Typ.Tptr (t, _) when Typ.is_array_of_cpp_class typ || is_dyn_array ->
Sil.Lindex (var_exp, Sil.Const (Sil.Cint (IntLit.of_int n))), t Sil.Lindex (var_exp, Sil.Const (Sil.Cint (IntLit.of_int n))), t
| _ -> var_exp, typ in | _ -> var_exp, typ in
let trans_state' = { trans_state with var_exp_typ = Some (var_exp_inside, typ_inside) } in let trans_state' = { trans_state with var_exp_typ = Some (var_exp_inside, typ_inside) } in
@ -2096,7 +2096,7 @@ struct
let init_stmt_info = { stmt_info with let init_stmt_info = { stmt_info with
Clang_ast_t.si_pointer = Ast_utils.get_fresh_pointer () } in Clang_ast_t.si_pointer = Ast_utils.get_fresh_pointer () } in
let res_trans_init = let res_trans_init =
if is_dyn_array && Sil.is_pointer_to_cpp_class typ then if is_dyn_array && Typ.is_pointer_to_cpp_class typ then
let rec create_stmts stmt_opt size_exp_opt = let rec create_stmts stmt_opt size_exp_opt =
match stmt_opt, size_exp_opt with match stmt_opt, size_exp_opt with
| Some stmt, Some (Sil.Const (Sil.Cint n)) when not (IntLit.iszero n) -> | Some stmt, Some (Sil.Const (Sil.Cint n)) when not (IntLit.iszero n) ->
@ -2174,13 +2174,13 @@ struct
let sil_loc = CLocation.get_sil_location stmt_info context in let sil_loc = CLocation.get_sil_location stmt_info context in
let cast_type = CTypes_decl.type_ptr_to_sil_type tenv cast_type_ptr in let cast_type = CTypes_decl.type_ptr_to_sil_type tenv cast_type_ptr in
let sizeof_expr = match cast_type with let sizeof_expr = match cast_type with
| Sil.Tptr (typ, _) -> Sil.Sizeof (typ, None, subtypes) | Typ.Tptr (typ, _) -> Sil.Sizeof (typ, None, subtypes)
| _ -> assert false in | _ -> assert false in
let builtin = Sil.Const (Sil.Cfun ModelBuiltins.__cast) in let builtin = Sil.Const (Sil.Cfun ModelBuiltins.__cast) in
let stmt = match stmts with [stmt] -> stmt | _ -> assert false in let stmt = match stmts with [stmt] -> stmt | _ -> assert false in
let res_trans_stmt = exec_with_glvalue_as_reference instruction trans_state' stmt in let res_trans_stmt = exec_with_glvalue_as_reference instruction trans_state' stmt in
let exp = match res_trans_stmt.exps with | [e] -> e | _ -> assert false in let exp = match res_trans_stmt.exps with | [e] -> e | _ -> assert false in
let args = [exp; (sizeof_expr, Sil.Tvoid)] in let args = [exp; (sizeof_expr, Typ.Tvoid)] in
let ret_id = Ident.create_fresh Ident.knormal in let ret_id = Ident.create_fresh Ident.knormal in
let call = Sil.Call ([ret_id], builtin, args, sil_loc, Sil.cf_default) in let call = Sil.Call ([ret_id], builtin, args, sil_loc, Sil.cf_default) in
let res_ex = Sil.Var ret_id in let res_ex = Sil.Var ret_id in
@ -2216,7 +2216,7 @@ struct
and cxxPseudoDestructorExpr_trans () = and cxxPseudoDestructorExpr_trans () =
let fun_name = Procname.from_string_c_fun CFrontend_config.infer_skip_fun in let fun_name = Procname.from_string_c_fun CFrontend_config.infer_skip_fun in
{ empty_res_trans with exps = [(Sil.Const (Sil.Cfun fun_name), Sil.Tvoid)] } { empty_res_trans with exps = [(Sil.Const (Sil.Cfun fun_name), Typ.Tvoid)] }
and cxxTypeidExpr_trans trans_state stmt_info stmts expr_info = and cxxTypeidExpr_trans trans_state stmt_info stmts expr_info =
let tenv = trans_state.context.CContext.tenv in let tenv = trans_state.context.CContext.tenv in
@ -2232,12 +2232,12 @@ struct
let fun_name = ModelBuiltins.__cxx_typeid in let fun_name = ModelBuiltins.__cxx_typeid in
let sil_fun = Sil.Const (Sil.Cfun fun_name) in let sil_fun = Sil.Const (Sil.Cfun fun_name) in
let ret_id = Ident.create_fresh Ident.knormal in let ret_id = Ident.create_fresh Ident.knormal in
let type_info_objc = (Sil.Sizeof (typ, None, Sil.Subtype.exact), Sil.Tvoid) in let type_info_objc = (Sil.Sizeof (typ, None, Sil.Subtype.exact), Typ.Tvoid) in
let field_name_decl = Ast_utils.make_qual_name_decl ["type_info"; "std"] "__type_name" in let field_name_decl = Ast_utils.make_qual_name_decl ["type_info"; "std"] "__type_name" in
let field_name = General_utils.mk_class_field_name field_name_decl in let field_name = General_utils.mk_class_field_name field_name_decl in
let ret_exp = Sil.Var ret_id in let ret_exp = Sil.Var ret_id in
let field_exp = Sil.Lfield (ret_exp, field_name, typ) in let field_exp = Sil.Lfield (ret_exp, field_name, typ) in
let args = [type_info_objc; (field_exp, Sil.Tvoid)] @ res_trans_subexpr.exps in let args = [type_info_objc; (field_exp, Typ.Tvoid)] @ res_trans_subexpr.exps in
let call_instr = Sil.Call ([ret_id], sil_fun, args, sil_loc, Sil.cf_default) in let call_instr = Sil.Call ([ret_id], sil_fun, args, sil_loc, Sil.cf_default) in
let res_trans_call = { empty_res_trans with let res_trans_call = { empty_res_trans with
instrs = [call_instr]; instrs = [call_instr];
@ -2553,7 +2553,7 @@ struct
implicitValueInitExpr_trans trans_state expr_info implicitValueInitExpr_trans trans_state expr_info
| GenericSelectionExpr _ (* to be fixed when we dump the right info in the ast *) | GenericSelectionExpr _ (* to be fixed when we dump the right info in the ast *)
| SizeOfPackExpr _ -> | SizeOfPackExpr _ ->
{ empty_res_trans with exps = [(Sil.exp_get_undefined false, Sil.Tvoid)] } { empty_res_trans with exps = [(Sil.exp_get_undefined false, Typ.Tvoid)] }
| GCCAsmStmt (stmt_info, stmts) -> | GCCAsmStmt (stmt_info, stmts) ->
gccAstStmt_trans trans_state stmt_info stmts gccAstStmt_trans trans_state stmt_info stmts
@ -2599,7 +2599,7 @@ struct
"WARNING: There should be one expression for 'this' in constructor. \n" in "WARNING: There should be one expression for 'this' in constructor. \n" in
(* Hack: Strip pointer from type here since cxxConstructExpr_trans expects it this way *) (* Hack: Strip pointer from type here since cxxConstructExpr_trans expects it this way *)
(* it will add pointer back before making it a parameter to a call *) (* it will add pointer back before making it a parameter to a call *)
let class_typ = match this_typ with Sil.Tptr (t, _) -> t | _ -> assert false in let class_typ = match this_typ with Typ.Tptr (t, _) -> t | _ -> assert false in
{ this_res_trans with exps = [this_exp, class_typ] } { this_res_trans with exps = [this_exp, class_typ] }
| `Member (decl_ref) -> | `Member (decl_ref) ->
decl_ref_trans trans_state' this_res_trans child_stmt_info decl_ref decl_ref_trans trans_state' this_res_trans child_stmt_info decl_ref

@ -31,7 +31,8 @@ let is_alloc_model typ funct =
else else
let funct = Procname.to_string procname in let funct = Procname.to_string procname in
(* if (Core_foundation_model.is_core_lib_create typ funct) then (* if (Core_foundation_model.is_core_lib_create typ funct) then
print_endline ("\nCore Foundation create not modelled "^(Sil.typ_to_string typ)^" "^(funct));*) print_endline ("\nCore Foundation create not modelled "
^(Typ.to_string typ)^" "^(funct));*)
Core_foundation_model.is_core_lib_create typ funct Core_foundation_model.is_core_lib_create typ funct
| None -> false | None -> false

@ -13,7 +13,7 @@ val is_cf_non_null_alloc : Procname.t option -> bool
val is_alloc : Procname.t option -> bool val is_alloc : Procname.t option -> bool
val is_alloc_model : Sil.typ -> Procname.t option -> bool val is_alloc_model : Typ.t -> Procname.t option -> bool
val is_objc_memory_model_controlled : string -> bool val is_objc_memory_model_controlled : string -> bool

@ -24,7 +24,7 @@ let extract_item_from_singleton l warning_string failure_val =
| [item] -> item | [item] -> item
| _ -> Printing.log_err "%s" warning_string; failure_val | _ -> Printing.log_err "%s" warning_string; failure_val
let dummy_exp = (Sil.exp_minus_one, Sil.Tint Sil.IInt) let dummy_exp = (Sil.exp_minus_one, Typ.Tint Typ.IInt)
(* Extract the element of a singleton list. If the list is not a singleton *) (* Extract the element of a singleton list. If the list is not a singleton *)
(* Gives a warning and return -1 as standard value indicating something *) (* Gives a warning and return -1 as standard value indicating something *)
@ -130,9 +130,9 @@ type trans_state = {
succ_nodes: Cfg.Node.t list; (* successor nodes in the cfg *) succ_nodes: Cfg.Node.t list; (* successor nodes in the cfg *)
continuation: continuation option; (* current continuation *) continuation: continuation option; (* current continuation *)
priority: priority_node; priority: priority_node;
var_exp_typ: (Sil.exp * Sil.typ) option; var_exp_typ: (Sil.exp * Typ.t) option;
opaque_exp: (Sil.exp * Sil.typ) option; opaque_exp: (Sil.exp * Typ.t) option;
obj_bridged_cast_typ : Sil.typ option obj_bridged_cast_typ : Typ.t option
} }
(* A translation result. It is returned by the translation function. *) (* A translation result. It is returned by the translation function. *)
@ -140,7 +140,7 @@ type trans_result = {
root_nodes: Cfg.Node.t list; (* Top cfg nodes (root) created by the translation *) root_nodes: Cfg.Node.t list; (* Top cfg nodes (root) created by the translation *)
leaf_nodes: Cfg.Node.t list; (* Bottom cfg nodes (leaf) created by the translate *) leaf_nodes: Cfg.Node.t list; (* Bottom cfg nodes (leaf) created by the translate *)
instrs: Sil.instr list; (* list of SIL instruction that need to be placed in cfg nodes of the parent*) instrs: Sil.instr list; (* list of SIL instruction that need to be placed in cfg nodes of the parent*)
exps: (Sil.exp * Sil.typ) list; (* SIL expressions resulting from the translation of the clang stmt *) exps: (Sil.exp * Typ.t) list; (* SIL expressions resulting from translation of clang stmt *)
initd_exps: Sil.exp list; initd_exps: Sil.exp list;
is_cpp_call_virtual : bool; is_cpp_call_virtual : bool;
} }
@ -289,20 +289,20 @@ end
let create_alloc_instrs context sil_loc function_type fname size_exp_opt procname_opt = let create_alloc_instrs context sil_loc function_type fname size_exp_opt procname_opt =
let function_type, function_type_np = let function_type, function_type_np =
match function_type with match function_type with
| Sil.Tptr (styp, Sil.Pk_pointer) | Typ.Tptr (styp, Typ.Pk_pointer)
| Sil.Tptr (styp, Sil.Pk_objc_weak) | Typ.Tptr (styp, Typ.Pk_objc_weak)
| Sil.Tptr (styp, Sil.Pk_objc_unsafe_unretained) | Typ.Tptr (styp, Typ.Pk_objc_unsafe_unretained)
| Sil.Tptr (styp, Sil.Pk_objc_autoreleasing) -> | Typ.Tptr (styp, Typ.Pk_objc_autoreleasing) ->
function_type, styp function_type, styp
| _ -> Sil.Tptr (function_type, Sil.Pk_pointer), function_type in | _ -> Typ.Tptr (function_type, Typ.Pk_pointer), function_type in
let function_type_np = CTypes.expand_structured_type context.CContext.tenv function_type_np in let function_type_np = CTypes.expand_structured_type context.CContext.tenv function_type_np in
let sizeof_exp_ = Sil.Sizeof (function_type_np, None, Sil.Subtype.exact) in let sizeof_exp_ = Sil.Sizeof (function_type_np, None, Sil.Subtype.exact) in
let sizeof_exp = match size_exp_opt with let sizeof_exp = match size_exp_opt with
| Some exp -> Sil.BinOp (Sil.Mult, sizeof_exp_, exp) | Some exp -> Sil.BinOp (Sil.Mult, sizeof_exp_, exp)
| None -> sizeof_exp_ in | None -> sizeof_exp_ in
let exp = (sizeof_exp, Sil.Tint Sil.IULong) in let exp = (sizeof_exp, Typ.Tint Typ.IULong) in
let procname_arg = match procname_opt with let procname_arg = match procname_opt with
| Some procname -> [Sil.Const (Sil.Cfun (procname)), Sil.Tvoid] | Some procname -> [Sil.Const (Sil.Cfun (procname)), Typ.Tvoid]
| None -> [] in | None -> [] in
let args = exp :: procname_arg in let args = exp :: procname_arg in
let ret_id = Ident.create_fresh Ident.knormal in let ret_id = Ident.create_fresh Ident.knormal in
@ -368,7 +368,7 @@ let create_cast_instrs context exp cast_from_typ cast_to_typ sil_loc =
let cast_typ_no_pointer = CTypes.expand_structured_type context.CContext.tenv typ in let cast_typ_no_pointer = CTypes.expand_structured_type context.CContext.tenv typ in
let sizeof_exp = Sil.Sizeof (cast_typ_no_pointer, None, Sil.Subtype.exact) in let sizeof_exp = Sil.Sizeof (cast_typ_no_pointer, None, Sil.Subtype.exact) in
let pname = ModelBuiltins.__objc_cast in let pname = ModelBuiltins.__objc_cast in
let args = [(exp, cast_from_typ); (sizeof_exp, Sil.Tint Sil.IULong)] in let args = [(exp, cast_from_typ); (sizeof_exp, Typ.Tint Typ.IULong)] in
let stmt_call = Sil.Call([ret_id], (Sil.Const (Sil.Cfun pname)), args, sil_loc, Sil.cf_default) in let stmt_call = Sil.Call([ret_id], (Sil.Const (Sil.Cfun pname)), args, sil_loc, Sil.cf_default) in
(stmt_call, Sil.Var ret_id) (stmt_call, Sil.Var ret_id)
@ -398,7 +398,7 @@ let dereference_var_sil (exp, typ) sil_loc =
let dereference_value_from_result sil_loc trans_result ~strip_pointer = let dereference_value_from_result sil_loc trans_result ~strip_pointer =
let (obj_sil, class_typ) = extract_exp_from_list trans_result.exps "" in let (obj_sil, class_typ) = extract_exp_from_list trans_result.exps "" in
let cast_inst, cast_exp = dereference_var_sil (obj_sil, class_typ) sil_loc in let cast_inst, cast_exp = dereference_var_sil (obj_sil, class_typ) sil_loc in
let typ_no_ptr = match class_typ with | Sil.Tptr (typ, _) -> typ | _ -> assert false in let typ_no_ptr = match class_typ with | Typ.Tptr (typ, _) -> typ | _ -> assert false in
let cast_typ = if strip_pointer then typ_no_ptr else class_typ in let cast_typ = if strip_pointer then typ_no_ptr else class_typ in
{ trans_result with { trans_result with
instrs = trans_result.instrs @ cast_inst; instrs = trans_result.instrs @ cast_inst;
@ -441,7 +441,7 @@ let cast_operation trans_state cast_kind exps cast_typ sil_loc is_objc_bridged =
let trans_assertion_failure sil_loc context = let trans_assertion_failure sil_loc context =
let assert_fail_builtin = Sil.Const (Sil.Cfun ModelBuiltins.__infer_fail) in let assert_fail_builtin = Sil.Const (Sil.Cfun ModelBuiltins.__infer_fail) in
let args = [Sil.Const (Sil.Cstr Config.default_failure_name), Sil.Tvoid] in let args = [Sil.Const (Sil.Cstr Config.default_failure_name), Typ.Tvoid] in
let call_instr = Sil.Call ([], assert_fail_builtin, args, sil_loc, Sil.cf_default) in let call_instr = Sil.Call ([], assert_fail_builtin, args, sil_loc, Sil.cf_default) in
let exit_node = Cfg.Procdesc.get_exit_node (CContext.get_procdesc context) let exit_node = Cfg.Procdesc.get_exit_node (CContext.get_procdesc context)
and failure_node = and failure_node =
@ -621,7 +621,7 @@ let rec contains_opaque_value_expr s =
(* checks if a unary operator is a logic negation applied to integers*) (* checks if a unary operator is a logic negation applied to integers*)
let is_logical_negation_of_int tenv ei uoi = let is_logical_negation_of_int tenv ei uoi =
match CTypes_decl.type_ptr_to_sil_type tenv ei.Clang_ast_t.ei_type_ptr, uoi.Clang_ast_t.uoi_kind with match CTypes_decl.type_ptr_to_sil_type tenv ei.Clang_ast_t.ei_type_ptr, uoi.Clang_ast_t.uoi_kind with
| Sil.Tint Sil.IInt,`LNot -> true | Typ.Tint Typ.IInt,`LNot -> true
| _, _ -> false | _, _ -> false
let rec is_block_stmt stmt = let rec is_block_stmt stmt =
@ -673,18 +673,18 @@ let var_or_zero_in_init_list tenv e typ ~return_zero:return_zero =
let rec var_or_zero_in_init_list' e typ tns = let rec var_or_zero_in_init_list' e typ tns =
let open General_utils in let open General_utils in
match typ with match typ with
| Sil.Tvar tn -> | Typ.Tvar tn ->
(match Tenv.lookup tenv tn with (match Tenv.lookup tenv tn with
| Some struct_typ -> var_or_zero_in_init_list' e (Sil.Tstruct struct_typ) tns | Some struct_typ -> var_or_zero_in_init_list' e (Typ.Tstruct struct_typ) tns
| _ -> [[(e, typ)]] (*This case is an error, shouldn't happen.*)) | _ -> [[(e, typ)]] (*This case is an error, shouldn't happen.*))
| Sil.Tstruct { Sil.instance_fields } as type_struct -> | Typ.Tstruct { Typ.instance_fields } as type_struct ->
let lh_exprs = IList.map ( fun (fieldname, _, _) -> let lh_exprs = IList.map ( fun (fieldname, _, _) ->
Sil.Lfield (e, fieldname, type_struct) ) instance_fields in Sil.Lfield (e, fieldname, type_struct) ) instance_fields in
let lh_types = IList.map ( fun (_, fieldtype, _) -> fieldtype) instance_fields in let lh_types = IList.map ( fun (_, fieldtype, _) -> fieldtype) instance_fields in
let exp_types = zip lh_exprs lh_types in let exp_types = zip lh_exprs lh_types in
IList.map (fun (e, t) -> IList.map (fun (e, t) ->
IList.flatten (var_or_zero_in_init_list' e t tns)) exp_types IList.flatten (var_or_zero_in_init_list' e t tns)) exp_types
| Sil.Tarray (arrtyp, Some n) -> | Typ.Tarray (arrtyp, Some n) ->
let size = IntLit.to_int n in let size = IntLit.to_int n in
let indices = list_range 0 (size - 1) in let indices = list_range 0 (size - 1) in
let index_constants = let index_constants =
@ -695,10 +695,10 @@ let var_or_zero_in_init_list tenv e typ ~return_zero:return_zero =
let exp_types = zip lh_exprs lh_types in let exp_types = zip lh_exprs lh_types in
IList.map (fun (e, t) -> IList.map (fun (e, t) ->
IList.flatten (var_or_zero_in_init_list' e t tns)) exp_types IList.flatten (var_or_zero_in_init_list' e t tns)) exp_types
| Sil.Tint _ | Sil.Tfloat _ | Sil.Tptr _ -> | Typ.Tint _ | Typ.Tfloat _ | Typ.Tptr _ ->
let exp = if return_zero then Sil.zero_value_of_numerical_type typ else e in let exp = if return_zero then Sil.zero_value_of_numerical_type typ else e in
[ [(exp, typ)] ] [ [(exp, typ)] ]
| Sil.Tfun _ | Sil.Tvoid | Sil.Tarray _ -> assert false in | Typ.Tfun _ | Typ.Tvoid | Typ.Tarray _ -> assert false in
IList.flatten (var_or_zero_in_init_list' e typ StringSet.empty) IList.flatten (var_or_zero_in_init_list' e typ StringSet.empty)
(* (*

@ -26,16 +26,16 @@ type trans_state = {
succ_nodes: Cfg.Node.t list; succ_nodes: Cfg.Node.t list;
continuation: continuation option; continuation: continuation option;
priority: priority_node; priority: priority_node;
var_exp_typ: (Sil.exp * Sil.typ) option; var_exp_typ: (Sil.exp * Typ.t) option;
opaque_exp: (Sil.exp * Sil.typ) option; opaque_exp: (Sil.exp * Typ.t) option;
obj_bridged_cast_typ : Sil.typ option obj_bridged_cast_typ : Typ.t option
} }
type trans_result = { type trans_result = {
root_nodes: Cfg.Node.t list; root_nodes: Cfg.Node.t list;
leaf_nodes: Cfg.Node.t list; leaf_nodes: Cfg.Node.t list;
instrs: Sil.instr list; instrs: Sil.instr list;
exps: (Sil.exp * Sil.typ) list; exps: (Sil.exp * Typ.t) list;
initd_exps: Sil.exp list; initd_exps: Sil.exp list;
is_cpp_call_virtual : bool; is_cpp_call_virtual : bool;
} }
@ -44,7 +44,7 @@ val empty_res_trans: trans_result
val collect_res_trans : Cfg.cfg -> trans_result list -> trans_result val collect_res_trans : Cfg.cfg -> trans_result list -> trans_result
val extract_var_exp_or_fail : trans_state -> Sil.exp * Sil.typ val extract_var_exp_or_fail : trans_state -> Sil.exp * Typ.t
val is_return_temp: continuation option -> bool val is_return_temp: continuation option -> bool
@ -56,15 +56,15 @@ val mk_cond_continuation : continuation option -> continuation option
val extract_item_from_singleton : 'a list -> string -> 'a -> 'a val extract_item_from_singleton : 'a list -> string -> 'a -> 'a
val extract_exp_from_list : (Sil.exp * Sil.typ) list -> string -> (Sil.exp * Sil.typ) val extract_exp_from_list : (Sil.exp * Typ.t) list -> string -> (Sil.exp * Typ.t)
val fix_param_exps_mismatch : 'a list -> (Sil.exp * Sil.typ) list -> (Sil.exp * Sil.typ)list val fix_param_exps_mismatch : 'a list -> (Sil.exp * Typ.t) list -> (Sil.exp * Typ.t)list
val get_selector_receiver : Clang_ast_t.obj_c_message_expr_info -> string * Clang_ast_t.receiver_kind val get_selector_receiver : Clang_ast_t.obj_c_message_expr_info -> string * Clang_ast_t.receiver_kind
val define_condition_side_effects : val define_condition_side_effects :
(Sil.exp * Sil.typ) list -> Sil.instr list -> Location.t -> (Sil.exp * Typ.t) list -> Sil.instr list -> Location.t ->
(Sil.exp * Sil.typ) list * Sil.instr list (Sil.exp * Typ.t) list * Sil.instr list
val extract_stmt_from_singleton : Clang_ast_t.stmt list -> string -> Clang_ast_t.stmt val extract_stmt_from_singleton : Clang_ast_t.stmt list -> string -> Clang_ast_t.stmt
@ -81,8 +81,8 @@ val get_type_from_exp_stmt : Clang_ast_t.stmt -> Clang_ast_t.type_ptr
val dereference_value_from_result : Location.t -> trans_result -> strip_pointer:bool -> trans_result val dereference_value_from_result : Location.t -> trans_result -> strip_pointer:bool -> trans_result
val cast_operation : val cast_operation :
trans_state -> Clang_ast_t.cast_kind -> (Sil.exp * Sil.typ) list -> Sil.typ -> Location.t -> trans_state -> Clang_ast_t.cast_kind -> (Sil.exp * Typ.t) list -> Typ.t -> Location.t ->
bool -> Sil.instr list * (Sil.exp * Sil.typ) bool -> Sil.instr list * (Sil.exp * Typ.t)
val trans_assertion: Location.t -> CContext.t -> Cfg.Node.t list -> trans_result val trans_assertion: Location.t -> CContext.t -> Cfg.Node.t list -> trans_result
@ -97,22 +97,22 @@ val contains_opaque_value_expr : Clang_ast_t.stmt -> bool
val get_decl_ref_info : Clang_ast_t.stmt -> Clang_ast_t.decl_ref val get_decl_ref_info : Clang_ast_t.stmt -> Clang_ast_t.decl_ref
val builtin_trans : trans_state -> Location.t -> Clang_ast_t.stmt_info -> val builtin_trans : trans_state -> Location.t -> Clang_ast_t.stmt_info ->
Sil.typ -> Procname.t option -> trans_result option Typ.t -> Procname.t option -> trans_result option
val alloc_trans : val alloc_trans :
trans_state -> Location.t -> Clang_ast_t.stmt_info -> Sil.typ -> bool -> trans_state -> Location.t -> Clang_ast_t.stmt_info -> Typ.t -> bool ->
Procname.t option -> trans_result Procname.t option -> trans_result
val new_or_alloc_trans : trans_state -> Location.t -> Clang_ast_t.stmt_info -> val new_or_alloc_trans : trans_state -> Location.t -> Clang_ast_t.stmt_info ->
Clang_ast_t.type_ptr -> string option -> string -> trans_result Clang_ast_t.type_ptr -> string option -> string -> trans_result
val cpp_new_trans : trans_state -> Location.t -> Sil.typ -> Sil.exp option -> trans_result val cpp_new_trans : trans_state -> Location.t -> Typ.t -> Sil.exp option -> trans_result
val cast_trans : val cast_trans :
CContext.t -> (Sil.exp * Sil.typ) list -> Location.t -> Procname.t option -> Sil.typ -> CContext.t -> (Sil.exp * Typ.t) list -> Location.t -> Procname.t option -> Typ.t ->
(Sil.instr * Sil.exp) option (Sil.instr * Sil.exp) option
val dereference_var_sil : Sil.exp * Sil.typ -> Location.t -> Sil.instr list * Sil.exp val dereference_var_sil : Sil.exp * Typ.t -> Location.t -> Sil.instr list * Sil.exp
(** Module for creating cfg nodes and other utility functions related to them. *) (** Module for creating cfg nodes and other utility functions related to them. *)
module Nodes : module Nodes :
@ -126,7 +126,7 @@ sig
val is_join_node : Cfg.Node.t -> bool val is_join_node : Cfg.Node.t -> bool
val create_prune_node : val create_prune_node :
bool -> (Sil.exp * Sil.typ) list -> Sil.instr list -> Location.t -> Sil.if_kind -> bool -> (Sil.exp * Typ.t) list -> Sil.instr list -> Location.t -> Sil.if_kind ->
CContext.t -> Cfg.Node.t CContext.t -> Cfg.Node.t
val is_prune_node : Cfg.Node.t -> bool val is_prune_node : Cfg.Node.t -> bool
@ -216,5 +216,5 @@ val is_dispatch_function : Clang_ast_t.stmt list -> int option
val is_block_enumerate_function : Clang_ast_t.obj_c_message_expr_info -> bool val is_block_enumerate_function : Clang_ast_t.obj_c_message_expr_info -> bool
val var_or_zero_in_init_list : Tenv.t -> Sil.exp -> Sil.typ -> return_zero:bool -> val var_or_zero_in_init_list : Tenv.t -> Sil.exp -> Typ.t -> return_zero:bool ->
(Sil.exp * Sil.typ) list (Sil.exp * Typ.t) list

@ -17,54 +17,54 @@ let get_builtin_objc_typename builtin_type =
| `ObjCClass -> Typename.TN_csu (Csu.Struct, (Mangled.from_string CFrontend_config.objc_class)) | `ObjCClass -> Typename.TN_csu (Csu.Struct, (Mangled.from_string CFrontend_config.objc_class))
let get_builtin_objc_type builtin_type = let get_builtin_objc_type builtin_type =
let typ = Sil.Tvar (get_builtin_objc_typename builtin_type) in let typ = Typ.Tvar (get_builtin_objc_typename builtin_type) in
match builtin_type with match builtin_type with
| `ObjCId -> typ | `ObjCId -> typ
| `ObjCClass -> Sil.Tptr (typ, Sil.Pk_pointer) | `ObjCClass -> Typ.Tptr (typ, Typ.Pk_pointer)
let sil_type_of_builtin_type_kind builtin_type_kind = let sil_type_of_builtin_type_kind builtin_type_kind =
match builtin_type_kind with match builtin_type_kind with
| `Void -> Sil.Tvoid | `Void -> Typ.Tvoid
| `Bool -> Sil.Tint Sil.IBool | `Bool -> Typ.Tint Typ.IBool
| `Char_U -> Sil.Tint Sil.IUChar | `Char_U -> Typ.Tint Typ.IUChar
| `UChar -> Sil.Tint Sil.IUChar | `UChar -> Typ.Tint Typ.IUChar
| `WChar_U -> Sil.Tint Sil.IUChar | `WChar_U -> Typ.Tint Typ.IUChar
| `Char_S -> Sil.Tint Sil.IChar | `Char_S -> Typ.Tint Typ.IChar
| `SChar -> Sil.Tint Sil.ISChar | `SChar -> Typ.Tint Typ.ISChar
| `WChar_S | `WChar_S
| `Char16 | `Char16
| `Char32 -> Sil.Tint Sil.IChar | `Char32 -> Typ.Tint Typ.IChar
| `UShort | `UShort
| `Short -> Sil.Tint Sil.IShort | `Short -> Typ.Tint Typ.IShort
| `UInt | `UInt
| `UInt128 -> Sil.Tint Sil.IUInt | `UInt128 -> Typ.Tint Typ.IUInt
| `ULong -> Sil.Tint Sil.IULong | `ULong -> Typ.Tint Typ.IULong
| `ULongLong -> Sil.Tint Sil.IULongLong | `ULongLong -> Typ.Tint Typ.IULongLong
| `Int | `Int
| `Int128 -> Sil.Tint Sil.IInt | `Int128 -> Typ.Tint Typ.IInt
| `Long -> Sil.Tint Sil.ILong | `Long -> Typ.Tint Typ.ILong
| `LongLong -> Sil.Tint Sil.ILongLong | `LongLong -> Typ.Tint Typ.ILongLong
| `Half -> Sil.Tint Sil.IShort (*?*) | `Half -> Typ.Tint Typ.IShort (*?*)
| `Float -> Sil.Tfloat Sil.FFloat | `Float -> Typ.Tfloat Typ.FFloat
| `Double -> Sil.Tfloat Sil.FDouble | `Double -> Typ.Tfloat Typ.FDouble
| `LongDouble -> Sil.Tfloat Sil.FLongDouble | `LongDouble -> Typ.Tfloat Typ.FLongDouble
| `NullPtr -> Sil.Tint Sil.IInt | `NullPtr -> Typ.Tint Typ.IInt
| `ObjCId -> get_builtin_objc_type `ObjCId | `ObjCId -> get_builtin_objc_type `ObjCId
| `ObjCClass -> get_builtin_objc_type `ObjCClass | `ObjCClass -> get_builtin_objc_type `ObjCClass
| _ -> Sil.Tvoid | _ -> Typ.Tvoid
let pointer_attribute_of_objc_attribute attr_info = let pointer_attribute_of_objc_attribute attr_info =
match attr_info.Clang_ast_t.ati_lifetime with match attr_info.Clang_ast_t.ati_lifetime with
| `OCL_None | `OCL_Strong -> Sil.Pk_pointer | `OCL_None | `OCL_Strong -> Typ.Pk_pointer
| `OCL_ExplicitNone -> Sil.Pk_objc_unsafe_unretained | `OCL_ExplicitNone -> Typ.Pk_objc_unsafe_unretained
| `OCL_Weak -> Sil.Pk_objc_weak | `OCL_Weak -> Typ.Pk_objc_weak
| `OCL_Autoreleasing -> Sil.Pk_objc_autoreleasing | `OCL_Autoreleasing -> Typ.Pk_objc_autoreleasing
let rec build_array_type translate_decl tenv type_ptr n_opt = let rec build_array_type translate_decl tenv type_ptr n_opt =
let array_type = type_ptr_to_sil_type translate_decl tenv type_ptr in let array_type = type_ptr_to_sil_type translate_decl tenv type_ptr in
let len = Option.map (fun n -> IntLit.of_int64 (Int64.of_int n)) n_opt in let len = Option.map (fun n -> IntLit.of_int64 (Int64.of_int n)) n_opt in
Sil.Tarray (array_type, len) Typ.Tarray (array_type, len)
and sil_type_of_attr_type translate_decl tenv type_info attr_info = and sil_type_of_attr_type translate_decl tenv type_info attr_info =
match type_info.Clang_ast_t.ti_desugared_type with match type_info.Clang_ast_t.ti_desugared_type with
@ -72,27 +72,27 @@ and sil_type_of_attr_type translate_decl tenv type_info attr_info =
(match Ast_utils.get_type type_ptr with (match Ast_utils.get_type type_ptr with
| Some Clang_ast_t.ObjCObjectPointerType (_, type_ptr') -> | Some Clang_ast_t.ObjCObjectPointerType (_, type_ptr') ->
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr' in let typ = type_ptr_to_sil_type translate_decl tenv type_ptr' in
Sil.Tptr (typ, pointer_attribute_of_objc_attribute attr_info) Typ.Tptr (typ, pointer_attribute_of_objc_attribute attr_info)
| _ -> type_ptr_to_sil_type translate_decl tenv type_ptr) | _ -> type_ptr_to_sil_type translate_decl tenv type_ptr)
| None -> Sil.Tvoid | None -> Typ.Tvoid
and sil_type_of_c_type translate_decl tenv c_type = and sil_type_of_c_type translate_decl tenv c_type =
let open Clang_ast_t in let open Clang_ast_t in
match c_type with match c_type with
| NoneType _ -> Sil.Tvoid | NoneType _ -> Typ.Tvoid
| BuiltinType (_, builtin_type_kind) -> | BuiltinType (_, builtin_type_kind) ->
sil_type_of_builtin_type_kind builtin_type_kind sil_type_of_builtin_type_kind builtin_type_kind
| PointerType (_, type_ptr) | PointerType (_, type_ptr)
| ObjCObjectPointerType (_, type_ptr) -> | ObjCObjectPointerType (_, type_ptr) ->
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in
if Sil.typ_equal typ (get_builtin_objc_type `ObjCClass) then if Typ.equal typ (get_builtin_objc_type `ObjCClass) then
typ typ
else Sil.Tptr (typ, Sil.Pk_pointer) else Typ.Tptr (typ, Typ.Pk_pointer)
| ObjCObjectType (_, objc_object_type_info) -> | ObjCObjectType (_, objc_object_type_info) ->
type_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type type_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type
| BlockPointerType (_, type_ptr) -> | BlockPointerType (_, type_ptr) ->
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in
Sil.Tptr (typ, Sil.Pk_pointer) Typ.Tptr (typ, Typ.Pk_pointer)
| IncompleteArrayType (_, type_ptr) | IncompleteArrayType (_, type_ptr)
| DependentSizedArrayType (_, type_ptr) | DependentSizedArrayType (_, type_ptr)
| VariableArrayType (_, type_ptr) -> | VariableArrayType (_, type_ptr) ->
@ -101,7 +101,7 @@ and sil_type_of_c_type translate_decl tenv c_type =
build_array_type translate_decl tenv type_ptr (Some n) build_array_type translate_decl tenv type_ptr (Some n)
| FunctionProtoType _ | FunctionProtoType _
| FunctionNoProtoType _ -> | FunctionNoProtoType _ ->
Sil.Tfun false Typ.Tfun false
| ParenType (_, type_ptr) -> | ParenType (_, type_ptr) ->
type_ptr_to_sil_type translate_decl tenv type_ptr type_ptr_to_sil_type translate_decl tenv type_ptr
| DecayedType (_, type_ptr) -> | DecayedType (_, type_ptr) ->
@ -112,44 +112,44 @@ and sil_type_of_c_type translate_decl tenv c_type =
| ElaboratedType (type_info) -> | ElaboratedType (type_info) ->
(match type_info.Clang_ast_t.ti_desugared_type with (match type_info.Clang_ast_t.ti_desugared_type with
Some type_ptr -> type_ptr_to_sil_type translate_decl tenv type_ptr Some type_ptr -> type_ptr_to_sil_type translate_decl tenv type_ptr
| None -> Sil.Tvoid) | None -> Typ.Tvoid)
| ObjCInterfaceType (_, pointer) -> | ObjCInterfaceType (_, pointer) ->
decl_ptr_to_sil_type translate_decl tenv pointer decl_ptr_to_sil_type translate_decl tenv pointer
| RValueReferenceType (_, type_ptr) | RValueReferenceType (_, type_ptr)
| LValueReferenceType (_, type_ptr) -> | LValueReferenceType (_, type_ptr) ->
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in
Sil.Tptr (typ, Sil.Pk_reference) Typ.Tptr (typ, Typ.Pk_reference)
| AttributedType (type_info, attr_info) -> | AttributedType (type_info, attr_info) ->
sil_type_of_attr_type translate_decl tenv type_info attr_info sil_type_of_attr_type translate_decl tenv type_info attr_info
| _ -> (* TypedefType, etc *) | _ -> (* TypedefType, etc *)
let type_info = Clang_ast_proj.get_type_tuple c_type in let type_info = Clang_ast_proj.get_type_tuple c_type in
match type_info.Clang_ast_t.ti_desugared_type with match type_info.Clang_ast_t.ti_desugared_type with
| Some typ -> type_ptr_to_sil_type translate_decl tenv typ | Some typ -> type_ptr_to_sil_type translate_decl tenv typ
| None -> Sil.Tvoid | None -> Typ.Tvoid
and decl_ptr_to_sil_type translate_decl tenv decl_ptr = and decl_ptr_to_sil_type translate_decl tenv decl_ptr =
let open Clang_ast_t in let open Clang_ast_t in
let typ = `DeclPtr decl_ptr in let typ = `DeclPtr decl_ptr in
try Clang_ast_types.TypePointerMap.find typ !CFrontend_config.sil_types_map try Clang_ast_types.TypePointerMap.find typ !CFrontend_config.sil_types_map
with Not_found -> with Not_found ->
match Ast_utils.get_decl decl_ptr with match Ast_utils.get_decl decl_ptr with
| Some (CXXRecordDecl _ as d) | Some (CXXRecordDecl _ as d)
| Some (RecordDecl _ as d) | Some (RecordDecl _ as d)
| Some (ClassTemplateSpecializationDecl _ as d) | Some (ClassTemplateSpecializationDecl _ as d)
| Some (ObjCInterfaceDecl _ as d) | Some (ObjCInterfaceDecl _ as d)
| Some (ObjCImplementationDecl _ as d) | Some (ObjCImplementationDecl _ as d)
| Some (ObjCProtocolDecl _ as d) | Some (ObjCProtocolDecl _ as d)
| Some (ObjCCategoryDecl _ as d) | Some (ObjCCategoryDecl _ as d)
| Some (ObjCCategoryImplDecl _ as d) | Some (ObjCCategoryImplDecl _ as d)
| Some (EnumDecl _ as d) -> translate_decl tenv d | Some (EnumDecl _ as d) -> translate_decl tenv d
| Some _ -> | Some _ ->
Printing.log_err "Warning: Wrong decl found for pointer %s " Printing.log_err "Warning: Wrong decl found for pointer %s "
(Clang_ast_j.string_of_pointer decl_ptr); (Clang_ast_j.string_of_pointer decl_ptr);
Sil.Tvoid Typ.Tvoid
| None -> | None ->
Printing.log_err "Warning: Decl pointer %s not found." Printing.log_err "Warning: Decl pointer %s not found."
(Clang_ast_j.string_of_pointer decl_ptr); (Clang_ast_j.string_of_pointer decl_ptr);
Sil.Tvoid Typ.Tvoid
and clang_type_ptr_to_sil_type translate_decl tenv type_ptr = and clang_type_ptr_to_sil_type translate_decl tenv type_ptr =
try try
@ -160,7 +160,7 @@ and clang_type_ptr_to_sil_type translate_decl tenv type_ptr =
let sil_type = sil_type_of_c_type translate_decl tenv c_type in let sil_type = sil_type_of_c_type translate_decl tenv c_type in
Ast_utils.update_sil_types_map type_ptr sil_type; Ast_utils.update_sil_types_map type_ptr sil_type;
sil_type sil_type
| _ -> Sil.Tvoid) | _ -> Typ.Tvoid)
and prebuilt_type_to_sil_type type_ptr = and prebuilt_type_to_sil_type type_ptr =
try try
@ -176,13 +176,13 @@ and type_ptr_to_sil_type translate_decl tenv type_ptr =
| `Prebuilt _ -> prebuilt_type_to_sil_type type_ptr | `Prebuilt _ -> prebuilt_type_to_sil_type type_ptr
| `PointerOf typ -> | `PointerOf typ ->
let sil_typ = type_ptr_to_sil_type translate_decl tenv typ in let sil_typ = type_ptr_to_sil_type translate_decl tenv typ in
Sil.Tptr (sil_typ, Sil.Pk_pointer) Typ.Tptr (sil_typ, Typ.Pk_pointer)
| `ReferenceOf typ -> | `ReferenceOf typ ->
let sil_typ = type_ptr_to_sil_type translate_decl tenv typ in let sil_typ = type_ptr_to_sil_type translate_decl tenv typ in
Sil.Tptr (sil_typ, Sil.Pk_reference) Typ.Tptr (sil_typ, Typ.Pk_reference)
| `ClassType (name, lang) -> | `ClassType (name, lang) ->
let kind = match lang with `OBJC -> Csu.Objc | `CPP -> Csu.CPP in let kind = match lang with `OBJC -> Csu.Objc | `CPP -> Csu.CPP in
Sil.Tvar (CTypes.mk_classname name kind) Typ.Tvar (CTypes.mk_classname name kind)
| `StructType name -> Sil.Tvar (CTypes.mk_structname name) | `StructType name -> Typ.Tvar (CTypes.mk_structname name)
| `DeclPtr ptr -> decl_ptr_to_sil_type translate_decl tenv ptr | `DeclPtr ptr -> decl_ptr_to_sil_type translate_decl tenv ptr
| `ErrorType -> Sil.Tvoid | `ErrorType -> Typ.Tvoid

@ -11,9 +11,9 @@ open! Utils
val get_builtin_objc_typename : [< `ObjCClass | `ObjCId ] -> Typename.t val get_builtin_objc_typename : [< `ObjCClass | `ObjCId ] -> Typename.t
val get_builtin_objc_type : [< `ObjCClass | `ObjCId ] -> Sil.typ val get_builtin_objc_type : [< `ObjCClass | `ObjCId ] -> Typ.t
val sil_type_of_builtin_type_kind : Clang_ast_t.builtin_type_kind -> Sil.typ val sil_type_of_builtin_type_kind : Clang_ast_t.builtin_type_kind -> Typ.t
val type_ptr_to_sil_type : (Tenv.t -> Clang_ast_t.decl -> Sil.typ) -> val type_ptr_to_sil_type : (Tenv.t -> Clang_ast_t.decl -> Typ.t) ->
Tenv.t -> Clang_ast_t.type_ptr -> Sil.typ Tenv.t -> Clang_ast_t.type_ptr -> Typ.t

@ -16,26 +16,26 @@ module L = Logging
let get_name_from_struct s = let get_name_from_struct s =
match s with match s with
| Sil.Tstruct { Sil.struct_name = Some n } -> n | Typ.Tstruct { Typ.struct_name = Some n } -> n
| _ -> assert false | _ -> assert false
let add_pointer_to_typ typ = let add_pointer_to_typ typ =
Sil.Tptr(typ, Sil.Pk_pointer) Typ.Tptr(typ, Typ.Pk_pointer)
let remove_pointer_to_typ typ = let remove_pointer_to_typ typ =
match typ with match typ with
| Sil.Tptr(typ, Sil.Pk_pointer) -> typ | Typ.Tptr(typ, Typ.Pk_pointer) -> typ
| _ -> typ | _ -> typ
let classname_of_type typ = let classname_of_type typ =
match typ with match typ with
| Sil.Tvar (Typename.TN_csu (_, name) ) | Typ.Tvar (Typename.TN_csu (_, name) )
| Sil.Tstruct { Sil.struct_name = Some name } | Typ.Tstruct { Typ.struct_name = Some name }
| Sil.Tvar (Typename.TN_typedef name) -> Mangled.to_string name | Typ.Tvar (Typename.TN_typedef name) -> Mangled.to_string name
| Sil.Tfun _ -> CFrontend_config.objc_object | Typ.Tfun _ -> CFrontend_config.objc_object
| _ -> | _ ->
Printing.log_out Printing.log_out
"Classname of type cannot be extracted in type %s" (Sil.typ_to_string typ); "Classname of type cannot be extracted in type %s" (Typ.to_string typ);
"undefined" "undefined"
let mk_classname n ck = Typename.TN_csu (Csu.Class ck, Mangled.from_string n) let mk_classname n ck = Typename.TN_csu (Csu.Class ck, Mangled.from_string n)
@ -46,8 +46,8 @@ let mk_enumname n = Typename.TN_enum (Mangled.from_string n)
let is_class typ = let is_class typ =
match typ with match typ with
| Sil.Tptr (Sil.Tstruct { Sil.struct_name = Some name }, _) | Typ.Tptr (Typ.Tstruct { Typ.struct_name = Some name }, _)
| Sil.Tptr (Sil.Tvar (Typename.TN_csu (_, name) ), _) -> | Typ.Tptr (Typ.Tvar (Typename.TN_csu (_, name) ), _) ->
(Mangled.to_string name) = CFrontend_config.objc_class (Mangled.to_string name) = CFrontend_config.objc_class
| _ -> false | _ -> false
@ -86,16 +86,16 @@ let is_reference_type tp =
(* Expand a named type Tvar if it has a definition in tenv. This is used for Tenum, Tstruct, etc. *) (* Expand a named type Tvar if it has a definition in tenv. This is used for Tenum, Tstruct, etc. *)
let rec expand_structured_type tenv typ = let rec expand_structured_type tenv typ =
match typ with match typ with
| Sil.Tvar tn -> | Typ.Tvar tn ->
(match Tenv.lookup tenv tn with (match Tenv.lookup tenv tn with
| Some ts -> | Some ts ->
let t = Sil.Tstruct ts in let t = Typ.Tstruct ts in
Printing.log_out " Type expanded with type '%s' found in tenv@." (Sil.typ_to_string t); Printing.log_out " Type expanded with type '%s' found in tenv@." (Typ.to_string t);
if Sil.typ_equal t typ then if Typ.equal t typ then
typ typ
else expand_structured_type tenv t else expand_structured_type tenv t
| None -> typ) | None -> typ)
| Sil.Tptr _ -> typ (*do not expand types under pointers *) | Typ.Tptr _ -> typ (*do not expand types under pointers *)
| _ -> typ | _ -> typ
(* To be called with strings of format "<pointer_type_info>*<class_name>" *) (* To be called with strings of format "<pointer_type_info>*<class_name>" *)
@ -111,7 +111,7 @@ let rec get_type_list nn ll =
| (n, t):: ll' -> (* Printing.log_out ">>>>>Searching for type '%s'. Seen '%s'.@." nn n; *) | (n, t):: ll' -> (* Printing.log_out ">>>>>Searching for type '%s'. Seen '%s'.@." nn n; *)
if n = nn then ( if n = nn then (
Printing.log_out ">>>>>>>>>>>>>>>>>>>>>>>NOW Found, Its type is: '%s'@." Printing.log_out ">>>>>>>>>>>>>>>>>>>>>>>NOW Found, Its type is: '%s'@."
(Sil.typ_to_string t); (Typ.to_string t);
[t] [t]
) else get_type_list nn ll' ) else get_type_list nn ll'
*) *)

@ -11,9 +11,9 @@ open! Utils
(** Utility module for retrieving types *) (** Utility module for retrieving types *)
val add_pointer_to_typ : Sil.typ -> Sil.typ val add_pointer_to_typ : Typ.t -> Typ.t
val classname_of_type : Sil.typ -> string val classname_of_type : Typ.t -> string
val mk_classname : string -> Csu.class_kind -> Typename.t val mk_classname : string -> Csu.class_kind -> Typename.t
@ -21,11 +21,11 @@ val mk_structname : string -> Typename.t
val mk_enumname : string -> Typename.t val mk_enumname : string -> Typename.t
val get_name_from_struct: Sil.typ -> Mangled.t val get_name_from_struct: Typ.t -> Mangled.t
val remove_pointer_to_typ : Sil.typ -> Sil.typ val remove_pointer_to_typ : Typ.t -> Typ.t
val is_class : Sil.typ -> bool val is_class : Typ.t -> bool
val return_type_of_function_type : Clang_ast_t.type_ptr -> Clang_ast_t.type_ptr val return_type_of_function_type : Clang_ast_t.type_ptr -> Clang_ast_t.type_ptr
@ -33,6 +33,6 @@ val is_block_type : Clang_ast_t.type_ptr -> bool
val is_reference_type : Clang_ast_t.type_ptr -> bool val is_reference_type : Clang_ast_t.type_ptr -> bool
val expand_structured_type : Tenv.t -> Sil.typ -> Sil.typ val expand_structured_type : Tenv.t -> Typ.t -> Typ.t
val get_name_from_type_pointer : string -> string * string val get_name_from_type_pointer : string -> string * string

@ -19,7 +19,7 @@ let add_predefined_objc_types tenv =
let class_typename = CType_to_sil_type.get_builtin_objc_typename `ObjCClass in let class_typename = CType_to_sil_type.get_builtin_objc_typename `ObjCClass in
let objc_class_type_info = let objc_class_type_info =
{ {
Sil.instance_fields = []; Typ.instance_fields = [];
static_fields = []; static_fields = [];
csu = Csu.Struct; csu = Csu.Struct;
struct_name = Some (Mangled.from_string CFrontend_config.objc_class); struct_name = Some (Mangled.from_string CFrontend_config.objc_class);
@ -31,7 +31,7 @@ let add_predefined_objc_types tenv =
let id_typename = CType_to_sil_type.get_builtin_objc_typename `ObjCId in let id_typename = CType_to_sil_type.get_builtin_objc_typename `ObjCId in
let objc_object_type_info = let objc_object_type_info =
{ {
Sil.instance_fields = []; Typ.instance_fields = [];
static_fields = []; static_fields = [];
csu = Csu.Struct; csu = Csu.Struct;
struct_name = Some (Mangled.from_string CFrontend_config.objc_object); struct_name = Some (Mangled.from_string CFrontend_config.objc_object);
@ -56,7 +56,7 @@ let add_predefined_basic_types () =
Ast_utils.update_sil_types_map tp return_type in Ast_utils.update_sil_types_map tp return_type in
let sil_void_type = CType_to_sil_type.sil_type_of_builtin_type_kind `Void in let sil_void_type = CType_to_sil_type.sil_type_of_builtin_type_kind `Void in
let sil_char_type = CType_to_sil_type.sil_type_of_builtin_type_kind `Char_S in let sil_char_type = CType_to_sil_type.sil_type_of_builtin_type_kind `Char_S in
let sil_nsarray_type = Sil.Tvar (CTypes.mk_classname CFrontend_config.nsarray_cl Csu.Objc) in let sil_nsarray_type = Typ.Tvar (CTypes.mk_classname CFrontend_config.nsarray_cl Csu.Objc) in
let sil_id_type = CType_to_sil_type.get_builtin_objc_type `ObjCId in let sil_id_type = CType_to_sil_type.get_builtin_objc_type `ObjCId in
add_basic_type create_int_type `Int; add_basic_type create_int_type `Int;
add_basic_type create_void_type `Void; add_basic_type create_void_type `Void;
@ -140,7 +140,7 @@ let get_superclass_list_cpp decl =
let add_struct_to_tenv tenv typ = let add_struct_to_tenv tenv typ =
let csu, struct_typ = match typ with let csu, struct_typ = match typ with
| Sil.Tstruct ({ Sil.csu } as struct_typ) -> csu, struct_typ | Typ.Tstruct ({ Typ.csu } as struct_typ) -> csu, struct_typ
| _ -> assert false in | _ -> assert false in
let mangled = CTypes.get_name_from_struct typ in let mangled = CTypes.get_name_from_struct typ in
let typename = Typename.TN_csu(csu, mangled) in let typename = Typename.TN_csu(csu, mangled) in
@ -176,21 +176,21 @@ and get_struct_cpp_class_declaration_type tenv decl =
let is_complete_definition = record_decl_info.Clang_ast_t.rdi_is_complete_definition in let is_complete_definition = record_decl_info.Clang_ast_t.rdi_is_complete_definition in
let sil_typename = Typename.TN_csu (csu, mangled_name) in let sil_typename = Typename.TN_csu (csu, mangled_name) in
let extra_fields = if CTrans_models.is_objc_memory_model_controlled name then let extra_fields = if CTrans_models.is_objc_memory_model_controlled name then
[Sil.objc_ref_counter_field] [Typ.objc_ref_counter_field]
else [] in else [] in
let struct_annotations = let struct_annotations =
if csu = Csu.Class Csu.CPP then Sil.cpp_class_annotation if csu = Csu.Class Csu.CPP then Typ.cpp_class_annotation
else Sil.item_annotation_empty in (* No annotations for structs *) else Typ.item_annotation_empty in (* No annotations for structs *)
if is_complete_definition then ( if is_complete_definition then (
Ast_utils.update_sil_types_map type_ptr (Sil.Tvar sil_typename); Ast_utils.update_sil_types_map type_ptr (Typ.Tvar sil_typename);
let non_static_fields = get_struct_fields tenv decl in let non_static_fields = get_struct_fields tenv decl in
let non_static_fields = let non_static_fields =
General_utils.append_no_duplicates_fields non_static_fields extra_fields in General_utils.append_no_duplicates_fields non_static_fields extra_fields in
let static_fields = [] in (* Note: We treat static field same as global variables *) let static_fields = [] in (* Note: We treat static field same as global variables *)
let def_methods = get_class_methods name decl_list in (* C++ methods only *) let def_methods = get_class_methods name decl_list in (* C++ methods only *)
let superclasses = get_superclass_list_cpp decl in let superclasses = get_superclass_list_cpp decl in
let sil_type = Sil.Tstruct { let sil_type = Typ.Tstruct {
Sil.instance_fields = non_static_fields; Typ.instance_fields = non_static_fields;
static_fields; static_fields;
csu; csu;
struct_name = Some mangled_name; struct_name = Some mangled_name;
@ -203,7 +203,7 @@ and get_struct_cpp_class_declaration_type tenv decl =
sil_type sil_type
) else ( ) else (
match Tenv.lookup tenv sil_typename with match Tenv.lookup tenv sil_typename with
| Some struct_typ -> Sil.Tstruct struct_typ (* just reuse what is already in tenv *) | Some struct_typ -> Typ.Tstruct struct_typ (* just reuse what is already in tenv *)
| None -> | None ->
(* This is first forward definition seen so far. Instead of adding *) (* This is first forward definition seen so far. Instead of adding *)
(* empty Tstruct to sil_types_map add Tvar so that frontend doeasn't expand *) (* empty Tstruct to sil_types_map add Tvar so that frontend doeasn't expand *)
@ -211,9 +211,9 @@ and get_struct_cpp_class_declaration_type tenv decl =
(* Later, when we see definition, it will be updated with a new value. *) (* Later, when we see definition, it will be updated with a new value. *)
(* Note: we know that this type will be wrapped with pointer type because *) (* Note: we know that this type will be wrapped with pointer type because *)
(* there was no full definition of that type yet. *) (* there was no full definition of that type yet. *)
let tvar_type = Sil.Tvar sil_typename in let tvar_type = Typ.Tvar sil_typename in
let empty_struct_type = Sil.Tstruct { let empty_struct_type = Typ.Tstruct {
Sil.instance_fields = extra_fields; Typ.instance_fields = extra_fields;
static_fields = []; static_fields = [];
csu; csu;
struct_name = Some mangled_name; struct_name = Some mangled_name;
@ -252,8 +252,8 @@ let get_type_from_expr_info ei tenv =
let class_from_pointer_type tenv type_ptr = let class_from_pointer_type tenv type_ptr =
match type_ptr_to_sil_type tenv type_ptr with match type_ptr_to_sil_type tenv type_ptr with
| Sil.Tptr( Sil.Tvar (Typename.TN_typedef name), _) -> Mangled.to_string name | Typ.Tptr( Typ.Tvar (Typename.TN_typedef name), _) -> Mangled.to_string name
| Sil.Tptr( Sil.Tvar (Typename.TN_csu (_, name)), _) -> Mangled.to_string name | Typ.Tptr( Typ.Tvar (Typename.TN_csu (_, name)), _) -> Mangled.to_string name
| _ -> assert false | _ -> assert false
let get_class_type_np tenv expr_info obj_c_message_expr_info = let get_class_type_np tenv expr_info obj_c_message_expr_info =
@ -265,5 +265,5 @@ let get_class_type_np tenv expr_info obj_c_message_expr_info =
let get_type_curr_class_objc tenv curr_class_opt = let get_type_curr_class_objc tenv curr_class_opt =
let name = CContext.get_curr_class_name curr_class_opt in let name = CContext.get_curr_class_name curr_class_opt in
let typ = Sil.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, (Mangled.from_string name))) in let typ = Typ.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, (Mangled.from_string name))) in
CTypes.expand_structured_type tenv typ CTypes.expand_structured_type tenv typ

@ -11,25 +11,25 @@ open! Utils
(** Processes types and record declarations by adding them to the tenv *) (** Processes types and record declarations by adding them to the tenv *)
val add_struct_to_tenv : Tenv.t -> Sil.typ -> unit val add_struct_to_tenv : Tenv.t -> Typ.t -> unit
val get_record_name : Clang_ast_t.decl -> string val get_record_name : Clang_ast_t.decl -> string
val add_types_from_decl_to_tenv : Tenv.t -> Clang_ast_t.decl -> Sil.typ val add_types_from_decl_to_tenv : Tenv.t -> Clang_ast_t.decl -> Typ.t
(* Adds the predefined types objc_class which is a struct, *) (* Adds the predefined types objc_class which is a struct, *)
(* and Class, which is a pointer to objc_class. *) (* and Class, which is a pointer to objc_class. *)
val add_predefined_types : Tenv.t -> unit val add_predefined_types : Tenv.t -> unit
val type_ptr_to_sil_type : Tenv.t -> Clang_ast_t.type_ptr -> Sil.typ val type_ptr_to_sil_type : Tenv.t -> Clang_ast_t.type_ptr -> Typ.t
val class_from_pointer_type : Tenv.t -> Clang_ast_t.type_ptr -> string val class_from_pointer_type : Tenv.t -> Clang_ast_t.type_ptr -> string
val get_class_type_np : Tenv.t -> Clang_ast_t.expr_info -> val get_class_type_np : Tenv.t -> Clang_ast_t.expr_info ->
Clang_ast_t.obj_c_message_expr_info -> Sil.typ Clang_ast_t.obj_c_message_expr_info -> Typ.t
val get_type_curr_class_objc : Tenv.t -> CContext.curr_class -> Sil.typ val get_type_curr_class_objc : Tenv.t -> CContext.curr_class -> Typ.t
val get_type_from_expr_info : Clang_ast_t.expr_info -> Tenv.t -> Sil.typ val get_type_from_expr_info : Clang_ast_t.expr_info -> Tenv.t -> Typ.t
val objc_class_name_to_sil_type : Tenv.t -> string -> Sil.typ val objc_class_name_to_sil_type : Tenv.t -> string -> Typ.t

@ -16,9 +16,9 @@ val sil_var_of_decl : CContext.t -> Clang_ast_t.decl -> Procname.t -> Pvar.t
val sil_var_of_decl_ref : CContext.t -> Clang_ast_t.decl_ref -> Procname.t -> Pvar.t val sil_var_of_decl_ref : CContext.t -> Clang_ast_t.decl_ref -> Procname.t -> Pvar.t
val add_var_to_locals : Cfg.Procdesc.t -> Clang_ast_t.decl -> Sil.typ -> Pvar.t -> unit val add_var_to_locals : Cfg.Procdesc.t -> Clang_ast_t.decl -> Typ.t -> Pvar.t -> unit
val compute_autorelease_pool_vars : CContext.t -> Clang_ast_t.stmt list -> (Sil.exp * Sil.typ) list val compute_autorelease_pool_vars : CContext.t -> Clang_ast_t.stmt list -> (Sil.exp * Typ.t) list
val captured_vars_from_block_info : CContext.t -> Clang_ast_t.block_captured_variable list -> val captured_vars_from_block_info : CContext.t -> Clang_ast_t.block_captured_variable list ->
(Pvar.t * Sil.typ) list (Pvar.t * Typ.t) list

@ -76,15 +76,15 @@ let process_category type_ptr_to_sil_type tenv curr_class decl_info decl_list =
let mang_name = Mangled.from_string class_name in let mang_name = Mangled.from_string class_name in
let class_tn_name = Typename.TN_csu (Csu.Class Csu.Objc, mang_name) in let class_tn_name = Typename.TN_csu (Csu.Class Csu.Objc, mang_name) in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar class_tn_name); Ast_utils.update_sil_types_map decl_key (Typ.Tvar class_tn_name);
(match Tenv.lookup tenv class_tn_name with (match Tenv.lookup tenv class_tn_name with
| Some ({ Sil.instance_fields; def_methods } as struct_typ) -> | Some ({ Typ.instance_fields; def_methods } as struct_typ) ->
let new_fields = General_utils.append_no_duplicates_fields fields instance_fields in let new_fields = General_utils.append_no_duplicates_fields fields instance_fields in
let new_methods = General_utils.append_no_duplicates_methods methods def_methods in let new_methods = General_utils.append_no_duplicates_methods methods def_methods in
let class_type_info = let class_type_info =
{ {
struct_typ with struct_typ with
Sil.instance_fields = new_fields; Typ.instance_fields = new_fields;
static_fields = []; static_fields = [];
csu = Csu.Class Csu.Objc; csu = Csu.Class Csu.Objc;
struct_name = Some mang_name; struct_name = Some mang_name;
@ -93,7 +93,7 @@ let process_category type_ptr_to_sil_type tenv curr_class decl_info decl_list =
Printing.log_out " Updating info for class '%s' in tenv\n" class_name; Printing.log_out " Updating info for class '%s' in tenv\n" class_name;
Tenv.add tenv class_tn_name class_type_info Tenv.add tenv class_tn_name class_type_info
| _ -> ()); | _ -> ());
Sil.Tvar class_tn_name Typ.Tvar class_tn_name
let category_decl type_ptr_to_sil_type tenv decl = let category_decl type_ptr_to_sil_type tenv decl =
let open Clang_ast_t in let open Clang_ast_t in

@ -14,9 +14,9 @@ open! Utils
open CFrontend_utils open CFrontend_utils
val category_decl : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Sil.typ val category_decl : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.t
val category_impl_decl : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Sil.typ val category_impl_decl : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.t
val noname_category : string -> string val noname_category : string -> string

@ -22,11 +22,11 @@ module L = Logging
let is_pointer_to_objc_class tenv typ = let is_pointer_to_objc_class tenv typ =
match typ with match typ with
| Sil.Tptr (Sil.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, cname)), _) -> | Typ.Tptr (Typ.Tvar (Typename.TN_csu (Csu.Class Csu.Objc, cname)), _) ->
(match Tenv.lookup tenv (Typename.TN_csu (Csu.Class Csu.Objc, cname)) with (match Tenv.lookup tenv (Typename.TN_csu (Csu.Class Csu.Objc, cname)) with
| Some struct_typ when Sil.is_objc_class (Sil.Tstruct struct_typ) -> true | Some struct_typ when Typ.is_objc_class (Typ.Tstruct struct_typ) -> true
| _ -> false) | _ -> false)
| Sil.Tptr (typ, _) when Sil.is_objc_class typ -> true | Typ.Tptr (typ, _) when Typ.is_objc_class typ -> true
| _ -> false | _ -> false
let get_super_interface_decl otdi_super = let get_super_interface_decl otdi_super =
@ -102,7 +102,7 @@ let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name
Printing.log_out "ADDING: ObjCInterfaceDecl for '%s'\n" class_name; Printing.log_out "ADDING: ObjCInterfaceDecl for '%s'\n" class_name;
let interface_name = CTypes.mk_classname class_name Csu.Objc in let interface_name = CTypes.mk_classname class_name Csu.Objc in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar interface_name); Ast_utils.update_sil_types_map decl_key (Typ.Tvar interface_name);
let superclasses, fields = let superclasses, fields =
create_superclasses_fields type_ptr_to_sil_type tenv curr_class decl_list create_superclasses_fields type_ptr_to_sil_type tenv curr_class decl_list
ocidi.Clang_ast_t.otdi_super ocidi.Clang_ast_t.otdi_super
@ -111,57 +111,57 @@ let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name
let fields_sc = CField_decl.fields_superclass tenv ocidi Csu.Objc in let fields_sc = CField_decl.fields_superclass tenv ocidi Csu.Objc in
IList.iter (fun (fn, ft, _) -> IList.iter (fun (fn, ft, _) ->
Printing.log_out "----->SuperClass field: '%s' " (Ident.fieldname_to_string fn); Printing.log_out "----->SuperClass field: '%s' " (Ident.fieldname_to_string fn);
Printing.log_out "type: '%s'\n" (Sil.typ_to_string ft)) fields_sc; Printing.log_out "type: '%s'\n" (Typ.to_string ft)) fields_sc;
(*In case we found categories, or partial definition of this class earlier and they are already in the tenv *) (*In case we found categories, or partial definition of this class earlier and they are already in the tenv *)
let fields, (superclasses : Typename.t list), methods = let fields, (superclasses : Typename.t list), methods =
match Tenv.lookup tenv interface_name with match Tenv.lookup tenv interface_name with
| Some ({ Sil.instance_fields; superclasses; def_methods }) -> | Some ({ Typ.instance_fields; superclasses; def_methods }) ->
General_utils.append_no_duplicates_fields fields instance_fields, General_utils.append_no_duplicates_fields fields instance_fields,
General_utils.append_no_duplicates_csu superclasses superclasses, General_utils.append_no_duplicates_csu superclasses superclasses,
General_utils.append_no_duplicates_methods methods def_methods General_utils.append_no_duplicates_methods methods def_methods
| _ -> fields, superclasses, methods in | _ -> fields, superclasses, methods in
let fields = General_utils.append_no_duplicates_fields fields fields_sc in let fields = General_utils.append_no_duplicates_fields fields fields_sc in
(* We add the special hidden counter_field for implementing reference counting *) (* We add the special hidden counter_field for implementing reference counting *)
let fields = General_utils.append_no_duplicates_fields [Sil.objc_ref_counter_field] fields in let fields = General_utils.append_no_duplicates_fields [Typ.objc_ref_counter_field] fields in
Printing.log_out "Class %s field:\n" class_name; Printing.log_out "Class %s field:\n" class_name;
IList.iter (fun (fn, _, _) -> IList.iter (fun (fn, _, _) ->
Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields; Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields;
let interface_type_info = let interface_type_info =
{ {
Sil.instance_fields = fields; Typ.instance_fields = fields;
static_fields = []; static_fields = [];
csu = Csu.Class Csu.Objc; csu = Csu.Class Csu.Objc;
struct_name = Some (Mangled.from_string class_name); struct_name = Some (Mangled.from_string class_name);
superclasses; superclasses;
def_methods = methods; def_methods = methods;
struct_annotations = Sil.objc_class_annotation; struct_annotations = Typ.objc_class_annotation;
} in } in
Tenv.add tenv interface_name interface_type_info; Tenv.add tenv interface_name interface_type_info;
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
| Some st -> Printing.log_out " >>>OK. Found typ='%s'\n" (Sil.typ_to_string (Sil.Tstruct st)) | Some st -> Printing.log_out " >>>OK. Found typ='%s'\n" (Typ.to_string (Typ.Tstruct st))
| None -> Printing.log_out " >>>NOT Found!!\n"); | None -> Printing.log_out " >>>NOT Found!!\n");
Sil.Tvar interface_name Typ.Tvar interface_name
let add_missing_methods tenv class_name ck decl_info decl_list curr_class = let add_missing_methods tenv class_name ck decl_info decl_list curr_class =
let methods = ObjcProperty_decl.get_methods curr_class decl_list in let methods = ObjcProperty_decl.get_methods curr_class decl_list in
let class_tn_name = Typename.TN_csu (Csu.Class ck, (Mangled.from_string class_name)) in let class_tn_name = Typename.TN_csu (Csu.Class ck, (Mangled.from_string class_name)) in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar class_tn_name); Ast_utils.update_sil_types_map decl_key (Typ.Tvar class_tn_name);
begin begin
match Tenv.lookup tenv class_tn_name with match Tenv.lookup tenv class_tn_name with
| Some ({ Sil.static_fields = []; | Some ({ Typ.static_fields = [];
csu = Csu.Class _; csu = Csu.Class _;
struct_name = Some _; struct_name = Some _;
def_methods; def_methods;
} as struct_typ) -> } as struct_typ) ->
let methods = General_utils.append_no_duplicates_methods def_methods methods in let methods = General_utils.append_no_duplicates_methods def_methods methods in
let struct_typ' = { struct_typ with Sil.def_methods = methods; } in let struct_typ' = { struct_typ with Typ.def_methods = methods; } in
Tenv.add tenv class_tn_name struct_typ' Tenv.add tenv class_tn_name struct_typ'
| _ -> () | _ -> ()
end; end;
Sil.Tvar class_tn_name Typ.Tvar class_tn_name
(* Interface_type_info has the name of instance variables and the name of methods. *) (* Interface_type_info has the name of instance variables and the name of methods. *)
let interface_declaration type_ptr_to_sil_type tenv decl = let interface_declaration type_ptr_to_sil_type tenv decl =

@ -15,12 +15,12 @@ open! Utils
open CFrontend_utils open CFrontend_utils
val interface_declaration : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> val interface_declaration : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl ->
Sil.typ Typ.t
val interface_impl_declaration : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> val interface_impl_declaration : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl ->
Sil.typ Typ.t
val is_pointer_to_objc_class : Tenv.t -> Sil.typ -> bool val is_pointer_to_objc_class : Tenv.t -> Typ.t -> bool
val get_curr_class : string -> Clang_ast_t.obj_c_interface_decl_info -> CContext.curr_class val get_curr_class : string -> Clang_ast_t.obj_c_interface_decl_info -> CContext.curr_class

@ -31,11 +31,11 @@ let protocol_decl type_ptr_to_sil_type tenv decl =
let mang_name = Mangled.from_string name in let mang_name = Mangled.from_string name in
let protocol_name = Typename.TN_csu (Csu.Protocol, mang_name) in let protocol_name = Typename.TN_csu (Csu.Protocol, mang_name) in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar protocol_name); Ast_utils.update_sil_types_map decl_key (Typ.Tvar protocol_name);
let def_methods = ObjcProperty_decl.get_methods curr_class decl_list in let def_methods = ObjcProperty_decl.get_methods curr_class decl_list in
let protocol_type_info = let protocol_type_info =
{ {
Sil.instance_fields = []; Typ.instance_fields = [];
static_fields = []; static_fields = [];
csu = Csu.Protocol; csu = Csu.Protocol;
struct_name = Some mang_name; struct_name = Some mang_name;
@ -45,7 +45,7 @@ let protocol_decl type_ptr_to_sil_type tenv decl =
} in } in
Tenv.add tenv protocol_name protocol_type_info; Tenv.add tenv protocol_name protocol_type_info;
add_protocol_super type_ptr_to_sil_type tenv obj_c_protocol_decl_info; add_protocol_super type_ptr_to_sil_type tenv obj_c_protocol_decl_info;
Sil.Tvar protocol_name Typ.Tvar protocol_name
| _ -> assert false | _ -> assert false
let is_protocol decl = let is_protocol decl =

@ -14,6 +14,6 @@ open! Utils
open CFrontend_utils open CFrontend_utils
val protocol_decl : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Sil.typ val protocol_decl : Ast_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.t
val is_protocol : Clang_ast_t.decl -> bool val is_protocol : Clang_ast_t.decl -> bool

@ -17,7 +17,7 @@ val callback_check_return_type : TypeCheck.check_return_type -> Callbacks.proc_c
(** Parameters of a call. *) (** Parameters of a call. *)
type parameters = (Sil.exp * Sil.typ) list type parameters = (Sil.exp * Typ.t) list
(** Type for a module that provides a main callback function *) (** Type for a module that provides a main callback function *)

@ -136,7 +136,7 @@ let check_condition case_zero find_canonical_duplicate curr_pname
let throwable_found = ref false in let throwable_found = ref false in
let throwable_class = Mangled.from_string "java.lang.Throwable" in let throwable_class = Mangled.from_string "java.lang.Throwable" in
let typ_is_throwable = function let typ_is_throwable = function
| Sil.Tstruct { Sil.csu = Csu.Class _; struct_name = Some c } -> | Typ.Tstruct { Typ.csu = Csu.Class _; struct_name = Some c } ->
Mangled.equal c throwable_class Mangled.equal c throwable_class
| _ -> false in | _ -> false in
let do_instr = function let do_instr = function
@ -257,7 +257,7 @@ let check_constructor_initialization
if Procname.is_constructor curr_pname if Procname.is_constructor curr_pname
then begin then begin
match PatternMatch.get_this_type (Cfg.Procdesc.get_attributes curr_pdesc) with match PatternMatch.get_this_type (Cfg.Procdesc.get_attributes curr_pdesc) with
| Some (Sil.Tptr (Sil.Tstruct { Sil.instance_fields; struct_name } as ts, _)) -> | Some (Typ.Tptr (Typ.Tstruct { Typ.instance_fields; struct_name } as ts, _)) ->
let do_field (fn, ft, _) = let do_field (fn, ft, _) =
let annotated_with f = match get_field_annotation fn ts with let annotated_with f = match get_field_annotation fn ts with
| None -> false | None -> false

@ -19,7 +19,7 @@ val const : Annotations.annotation -> bool -> TypeOrigin.t -> t
val descr_origin : t -> TypeErr.origin_descr val descr_origin : t -> TypeErr.origin_descr
val equal : t -> t -> bool val equal : t -> t -> bool
val from_item_annotation : Sil.item_annotation -> TypeOrigin.t -> t val from_item_annotation : Typ.item_annotation -> 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

@ -144,7 +144,7 @@ module ComplexExpressions = struct
end (* ComplexExpressions *) end (* ComplexExpressions *)
type check_return_type = type check_return_type =
Procname.t -> Cfg.Procdesc.t -> Sil.typ -> Sil.typ option -> Location.t -> unit Procname.t -> Cfg.Procdesc.t -> Typ.t -> Typ.t option -> Location.t -> unit
type find_canonical_duplicate = Cfg.Node.t -> Cfg.Node.t type find_canonical_duplicate = Cfg.Node.t -> Cfg.Node.t
@ -467,7 +467,7 @@ let typecheck_instr
(* check if there are errors in exp1 *) (* check if there are errors in exp1 *)
let typecheck_expr_for_errors typestate1 exp1 loc1 : unit = let typecheck_expr_for_errors typestate1 exp1 loc1 : unit =
ignore (typecheck_expr_simple typestate1 exp1 Sil.Tvoid TypeOrigin.Undef loc1) in ignore (typecheck_expr_simple typestate1 exp1 Typ.Tvoid TypeOrigin.Undef loc1) in
match instr with match instr with
| Sil.Remove_temps (idl, _) -> | Sil.Remove_temps (idl, _) ->
@ -553,7 +553,7 @@ let typecheck_instr
TypeState.add_id TypeState.add_id
id id
( (
Sil.Tint (Sil.IInt), Typ.Tint (Typ.IInt),
TypeAnnotation.const Annotations.Nullable false TypeOrigin.New, TypeAnnotation.const Annotations.Nullable false TypeOrigin.New,
[loc] [loc]
) )
@ -585,13 +585,13 @@ let typecheck_instr
etl_ in etl_ in
let ret_type = let ret_type =
match Tenv.proc_extract_return_typ tenv callee_pname_java with match Tenv.proc_extract_return_typ tenv callee_pname_java with
| Some (Sil.Tstruct _ as typ) -> | Some (Typ.Tstruct _ as typ) ->
Sil.Tptr (typ, Pk_pointer) Typ.Tptr (typ, Pk_pointer)
| Some typ -> | Some typ ->
typ typ
| None -> | None ->
let ret_typ_string = Procname.java_get_return_type callee_pname_java in let ret_typ_string = Procname.java_get_return_type callee_pname_java in
Sil.Tptr (Tvar (Typename.Java.from_string ret_typ_string), Pk_pointer) in Typ.Tptr (Tvar (Typename.Java.from_string ret_typ_string), Pk_pointer) in
let proc_attributes = let proc_attributes =
{ (ProcAttributes.default callee_pname Config.Java) with { (ProcAttributes.default callee_pname Config.Java) with
ProcAttributes.formals; ProcAttributes.formals;
@ -922,7 +922,7 @@ let typecheck_instr
Pvar.mk (Mangled.from_string e_str) curr_pname in Pvar.mk (Mangled.from_string e_str) curr_pname in
let e1 = Sil.Lvar pvar in let e1 = Sil.Lvar pvar in
let (typ, ta, _) = let (typ, ta, _) =
typecheck_expr_simple typestate e1 Sil.Tvoid TypeOrigin.ONone loc in typecheck_expr_simple typestate e1 Typ.Tvoid TypeOrigin.ONone loc in
let range = (typ, ta, [loc]) in let range = (typ, ta, [loc]) in
let typestate1 = TypeState.add pvar range typestate in let typestate1 = TypeState.add pvar range typestate in
typestate1, e1, EradicateChecks.From_containsKey typestate1, e1, EradicateChecks.From_containsKey
@ -955,7 +955,7 @@ let typecheck_instr
typestate, e, EradicateChecks.From_condition in typestate, e, EradicateChecks.From_condition in
let e', typestate2 = convert_complex_exp_to_pvar node' false e1 typestate1 loc in let e', typestate2 = convert_complex_exp_to_pvar node' false e1 typestate1 loc in
let (typ, ta, _) = let (typ, ta, _) =
typecheck_expr_simple typestate2 e' Sil.Tvoid TypeOrigin.ONone loc in typecheck_expr_simple typestate2 e' Typ.Tvoid TypeOrigin.ONone loc in
if checks.eradicate then if checks.eradicate then
EradicateChecks.check_zero EradicateChecks.check_zero
@ -1002,7 +1002,7 @@ let typecheck_instr
end in end in
let e', typestate2 = convert_complex_exp_to_pvar node' false e1 typestate1 loc in let e', typestate2 = convert_complex_exp_to_pvar node' false e1 typestate1 loc in
let (typ, ta, _) = let (typ, ta, _) =
typecheck_expr_simple typestate2 e' Sil.Tvoid TypeOrigin.ONone loc in typecheck_expr_simple typestate2 e' Typ.Tvoid TypeOrigin.ONone loc in
if checks.eradicate then if checks.eradicate then
EradicateChecks.check_nonzero find_canonical_duplicate curr_pname EradicateChecks.check_nonzero find_canonical_duplicate curr_pname

@ -13,7 +13,7 @@ open! Utils
(** Module type for the type checking functions. *) (** Module type for the type checking functions. *)
type check_return_type = type check_return_type =
Procname.t -> Cfg.Procdesc.t -> Sil.typ -> Sil.typ option -> Location.t -> unit Procname.t -> Cfg.Procdesc.t -> Typ.t -> Typ.t option -> Location.t -> unit
type find_canonical_duplicate = Cfg.Node.t -> Cfg.Node.t type find_canonical_duplicate = Cfg.Node.t -> Cfg.Node.t

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save