Module type Type_domain.S

type t = Ctypes.typ

PtrT {ptyp;idx;fe;ofs;ppred} abstracts the type ptyp.o* with ppred, with o = i * sizeof(ptyp) + ofs, where i belongs to the concretizations of both idx and fe.

val array_index_size : int

Size in bits of the array index argument to ParamT.

val index_zero : BR.Scalar.Context.t -> BR.binary
val index_minus_one : BR.Scalar.Context.t -> BR.binary
val offset_size : int

Size in bits of the struct offset argument to ParamT.

val eq : only_descr:bool -> BR.Scalar.Context.t -> t -> t -> bool
val imprecise_eq : t -> t -> bool

A more imprecise equality between ts that does not require a context. The difference is in the comparison between the array indices (of type BR.binary). The only guarantee on this function is that if t and u are not equal, then imprecise_eq t u is false.

exception Global_symbol_not_found
val fresh_symbol : unit -> string
val symbol : BR.Scalar.Context.t -> string -> int * BR.binary * t

Retrieve the abstract numeric value corresponding to a global symbolic constant (along with its size in bits). May throw Global_symbol_not_found.

val simple_symbol : BR.Scalar.Context.t -> string -> int * BR.binary * t
val add_symbol : BR.Scalar.Context.t -> string -> int -> BR.binary -> t -> unit
val is_symbol : BR.Scalar.Context.t -> string -> bool
val type_of_binary : BR.Scalar.Context.t -> BR.binary -> t option

Utility functions to manipulate predicates over abstract values of the numeric domain. These functions are not really about types but it was convenient to put them here.

val cond_of_pred_subdomain : size:int -> BR.Scalar.Context.t -> Ctypes.Pred.t -> BR.binary -> BR.boolean
val check_invariant_subdomain : size:int -> BR.Scalar.Context.t -> Ctypes.Pred.t -> BR.binary -> bool
val compare : t -> t -> int

Required by the domain signature, but don't expect this order to make any sense. WARNING: this function is NOT the lattice comparison function!

val pp : BR.Scalar.Context.t -> Stdlib.Format.formatter -> t -> unit
exception Type_error of string
val join : BR.Scalar.Context.t -> t -> t -> t option
val serialize_with_bottom_left : BR.Scalar.Context.t -> BR.Scalar.Context.t -> t -> 'a BR.Scalar.Context.in_acc -> (t, 'a) BR.Scalar.Context.result
val serialize_with_bottom_right : BR.Scalar.Context.t -> t -> BR.Scalar.Context.t -> 'a BR.Scalar.Context.in_acc -> (t, 'a) BR.Scalar.Context.result
type dereferenced_value = Ctypes.typ
val deref : size:int -> BR.Scalar.Context.t -> t -> (int * dereferenced_value) list

We represent the result of dereferencing a type as a sequence of word-sized types for ease of type checking upon store. This does not endanger soundness nor precision since we do not support predicates on product types yet. The return value is a list of (size in bytes, type) pairs, obtained by dereferencing the argument type which must be of size bytes. May throw a Type_error.

val deref_to_ctype : size:int -> BR.Scalar.Context.t -> t -> Ctypes.typ

Simpler version of above.

val dereferenced_value_of_typ : size:int -> BR.Scalar.Context.t -> Ctypes.typ list -> (int * dereferenced_value) list

Temporary.

val subtype : BR.Scalar.Context.t -> t -> t -> bool

Lattice comparison function.

val may_subtype : BR.Scalar.Context.t -> t -> t -> bool

Non-standard but needed operator. See notes. Returns true iff one of the concrete types in the concretization of the first operand is a subtype of one of the concrete types in the concretization of the first operand.

val add_offset : BR.Scalar.Context.t -> BR.Binary.t -> t -> t

add_offset ctx t ~idx ~fe ~old_ofs ~pred ~incr returns the result of adding the abstract offset incr to a pointer to t, with an index described by idx and fe and an offset in the pointed object old_ofs.

val in_bounds : BR.Scalar.Context.t -> t -> bool

Determines whether the offset associated with a pointer is in the bounds of the pointed type. Assumes that the argument has been produced using only applications of add_offset starting from a zero-offset pointer, and not crafted by other means. As a consequence, this operation only makes sense on arrays, since only on array pointers can add_offset return an out-of-bounds pointer. On pointers to non-array types, it returns true.

val is_empty : BR.Scalar.Context.t -> t -> bool

Returns true iff the concretization of the type is empty, i.e. if the concretization of the index is the empty set.