Frama-C API - Dom
include Frama_c_kernel.Datatype.S_with_collections with type t = state
include Frama_c_kernel.Datatype.S with type t = state
include Frama_c_kernel.Datatype.S_no_copy with type t = state
include Frama_c_kernel.Datatype.Ty with type t = state
type t = state
val ty : t Frama_c_kernel.Type.t
val descr : t Frama_c_kernel.Descr.t
Datatype descriptor.
val packed_descr : Frama_c_kernel.Structural_descr.pack
Packed version of the descriptor.
val reprs : t list
List of representants of the descriptor.
val hash : t -> int
Hash function: same spec than Hashtbl.hash
.
val pretty : Stdlib.Format.formatter -> t -> unit
Pretty print each value in an user-friendly way.
val mem_project : (Frama_c_kernel.Project_skeleton.t -> bool) -> t -> bool
mem_project f x
must return true
iff there is a value p
of type Project.t
in x
such that f p
returns true
.
module Set : Frama_c_kernel.Datatype.Set with type elt = t
module Map : Frama_c_kernel.Datatype.Map with type key = t
module Hashtbl : Frama_c_kernel.Datatype.Hashtbl with type key = t
Lattice Structure
val top : t
Greatest element.
val widen : Frama_c_kernel.Cil_types.kernel_function -> Frama_c_kernel.Cil_types.stmt -> t -> t -> t
widen h t1 t2
is an over-approximation of join t1 t2
. Assumes is_included t1 t2
val narrow : t -> t -> t Eva.Eval.or_bottom
Over-approximation of the intersection of two abstract states (called meet in the literature). Used only to gain some precision when interpreting the complete behaviors of a function specification. Can be very imprecise without impeding the analysis: meet x y = `Value x
is always sound.
Queries
type context = Ctx.t
Domains can optionally provide a context to be used by value abstractions when evaluating expressions. This can be safely ignored for most domains. Defined as unit (no context) by Domain_builder.Complete
.
type value = Val.t
Numerical values to which the expressions are evaluated.
type location = Loc.location
Abstract memory locations associated to left values.
The origin
is used by the domain combiners to track the origin of a value. An abstract domain can always use a dummy type unit for origin, or use it to encode some specific information about a value.
Queries functions return a pair of:
- the set of alarms that ensures the of the soundness of the evaluation of
exp
.Alarmset.all
is always a sound over-approximation of these alarms. - a value for the expression, which can be: – `Bottom if its evaluation is infeasible; – `Value (v, o) where
v
is an over-approximation of the abstract value of the expressionexp
, ando
is the origin of the value, which can be None.
When evaluating an expression, the evaluation engine asks the domains for abstract values and alarms at each lvalue (via extract_lval
) and each sub-expressions (via extract_expr
). In these queries:
oracle
is an evaluation function and can be used to find the answer by evaluating some others expressions, especially by relational domain. No recursive evaluation should be done by this function.context
record gives some information about the current evaluation.
val extract_expr : oracle:(Eva.Eval.exp -> value Eva.Eval.evaluated) -> Eva__.Abstract_domain.evaluation_context -> t -> Eva.Eval.exp -> (value * origin option) Eva.Eval.evaluated
Query function for compound expressions: extract_expr ~oracle context t exp
returns the known value of exp
by the state t
. See above for more details on queries.
val extract_lval : oracle:(Eva.Eval.exp -> value Eva.Eval.evaluated) -> Eva__.Abstract_domain.evaluation_context -> t -> Eva.Eval.lval -> location -> (value * origin option) Eva.Eval.evaluated
Query function for lvalues: extract_lval ~oracle context t lval loc
returns the known value stored at the location loc
of the left value lval
. See above for more details on queries.
val backward_location : t -> Eva.Eval.lval -> location -> value -> (location * value) Eva.Eval.or_bottom
backward_location state lval typ loc v
reduces the location loc
of the lvalue lval
, so that only the locations that may have value v
are kept. The returned location must be included in loc
, but it is always sound to return loc
itself. Also returns the value that may have the returned location, if not bottom. Defined by Domain_builder.Complete
with no reduction.
val reduce_further : t -> Eva.Eval.exp -> value -> (Eva.Eval.exp * value) list
Given a reduction expr
= value
, provides more reductions that may be performed. Defined by Domain_builder.Complete
with no reduction.
val build_context : t -> context Eva.Eval.or_bottom
Returns the current context to be used by value abstractions for the evaluation of expressions or lvalues. Defined by Domain_builder.Complete
with no context.
Transfer Functions
Transfer functions from the result of evaluations. See Eval
for more details about valuation.
update valuation t
updates the state t
with the values of expressions and the locations of lvalues available in the valuation
record.
val assign : Frama_c_kernel.Cil_types.kinstr -> location Eva.Eval.left_value -> Eva.Eval.exp -> (location, value) Eva.Eval.assigned -> (value, location, origin) Eva__.Abstract_domain.valuation -> t -> t Eva.Eval.or_bottom
assign kinstr lv expr v valuation state
is the transfer function for the assignment lv = expr
for state
. It must return the state where the assignment has been performed.
kinstr
is the statement of the assignment, or Kglobal for the initialization of a global variable.- when the kinstr is a function call,
expr
is the special variable in!Eval.call.return
. v
carries the value being assigned tolv
, i.e. the value of the expressionexpr
.v
also denotes the kind of assignment: Assign for the default assignment of the value, or Copy for the exact copy of a location if the right expressionexpr
is a lvalue.valuation
is a cache of all sub-expressions and locations computed for the evaluation oflval
andexpr
; it can also be used to reduce the state.
val assume : Frama_c_kernel.Cil_types.stmt -> Eva.Eval.exp -> bool -> (value, location, origin) Eva__.Abstract_domain.valuation -> t -> t Eva.Eval.or_bottom
Transfer function for an assumption. assume stmt expr bool valuation state
returns a state in which the boolean expression expr
evaluates to bool
.
stmt
is the statement of the assumption.valuation
is a cache of all sub-expressions and locations computed for the evaluation and the reduction ofexpr
; it can also be used to reduce the state.
val start_call : Frama_c_kernel.Cil_types.stmt -> (location, value) Eva.Eval.call -> Eva.Eval.recursion option -> (value, location, origin) Eva__.Abstract_domain.valuation -> t -> t Eva.Eval.or_bottom
start_call stmt call recursion valuation state
returns an initial state for the analysis of a called function. In particular, this function should introduce the formal parameters in the state, if necessary.
stmt
is the statement of the call site;call
represents the call: the called function and the arguments;recursion
is the information needed to interpret a recursive call. It is None if the call is not recursive.state
is the abstract state at the call site, before the call;valuation
is a cache for all values and locations computed during the evaluation of the function and its arguments.
On recursive calls, recursion
contains some substitution of variables to be applied on the domain state to prevent mixing up local variables and formal parameters of different recursive calls. See Eval.recursion
for more details. This substitution has been applied on values and expressions in call
, but not in the valuation
given as argument. If the domain uses some information from the valuation
on a recursive call, it must apply the substitution on it.
val finalize_call : Frama_c_kernel.Cil_types.stmt -> (location, value) Eva.Eval.call -> Eva.Eval.recursion option -> pre:t -> post:t -> t Eva.Eval.or_bottom
finalize_call stmt call ~pre ~post
computes the state after a function call, given the state pre
before the call, and the state post
at the end of the called function.
stmt
is the statement of the call site;call
represents the function call and its arguments.recursion
is the information needed to interpret a recursive call. It is None if the call is not recursive.pre
andpost
are the states before and at the end of the call respectively.
val show_expr : (value, location, origin) Eva__.Abstract_domain.valuation -> t -> Stdlib.Format.formatter -> Eva.Eval.exp -> unit
Called on the Frama_C_domain_show_each directive. Prints the internal properties inferred by the domain in the state
about the expression exp
. Can use the valuation
resulting from the cooperative evaluation of the expression. Defined by Domain_builder.Complete
but prints nothing.
Logic
Logical evaluation. This API is subject to changes.
logic_assign None loc state
removes from state
all inferred properties that depend on the memory location loc
. If the first argument is not None, it contains the logical clause being interpreted and the pre-state in which the terms of the clause are evaluated. The clause can be an assigns, allocates or frees clause. loc
is then the memory location concerned by the clause.
val evaluate_predicate : state Eva__.Abstract_domain.logic_environment -> state -> Frama_c_kernel.Cil_types.predicate -> Frama_c_kernel.Abstract_interp.Comp.result
Evaluates a predicate
to a logical status in the current state
. The logic_environment
contains the states at some labels and the potential variable for \result. Defined by Domain_builder.Complete
: all predicates are Unknown.
val reduce_by_predicate : state Eva__.Abstract_domain.logic_environment -> state -> Frama_c_kernel.Cil_types.predicate -> bool -> state Eva.Eval.or_bottom
reduce_by_predicate env state pred b
reduces the current state
by assuming that the predicate pred
evaluates to b
. env
contains the states at some labels and the potential variable for \result. Defined by Domain_builder.Complete
with no reduction.
val interpret_acsl_extension : Frama_c_kernel.Cil_types.acsl_extension -> state Eva__.Abstract_domain.logic_environment -> state -> state
Interprets an ACSL extension. Defined by Domain_builder.Complete
as the identity.
Scoping and initialization
Scoping: abstract transformers for entering and exiting blocks. The variables should be added or removed from the abstract state here. Note that the formals of a called function enter the scope through the transfer function start_call
, and leave it through a call to leave_scope
.
val enter_scope : Eva__.Abstract_domain.variable_kind -> Frama_c_kernel.Cil_types.varinfo list -> t -> t
Introduces a list of variables in the state. At this point, the variables are uninitialized. Globals and formals of the 'main' will be initialized by initialize_variable
and initialize_variable_using_type
. Local variables remain uninitialized until an assignment through assign
. The formal parameters of a call enter the scope through start_call
.
val leave_scope : Frama_c_kernel.Cil_types.kernel_function -> Frama_c_kernel.Cil_types.varinfo list -> t -> t
Removes a list of local and formal variables from the state. The first argument is the englobing function.
val empty : unit -> t
The initial state with which the analysis start.
val initialize_variable : Eva.Eval.lval -> location -> initialized:bool -> Eva__.Abstract_domain.init_value -> t -> t
initialize_variable lval loc ~initialized init_value state
initializes the value of the location loc
of lvalue lval
in state
with: – bits 0 if init_value = Zero; – any bits if init_value = Top. The boolean initialized is true if the location is initialized, and false if the location may be not initialized.
val initialize_variable_using_type : Eva__.Abstract_domain.variable_kind -> Frama_c_kernel.Cil_types.varinfo -> t -> t
Initializes a variable according to its type. The variable can be:
- a global variable on lib-entry mode.
- a formal parameter of the 'main' function.
- the return variable of a function specification.
Miscellaneous
Transfer functions called when entering/leaving a loop, and at each loop iteration. Defined as identity by Domain_builder.Complete
.
val enter_loop : Frama_c_kernel.Cil_types.stmt -> state -> state
val incr_loop_counter : Frama_c_kernel.Cil_types.stmt -> state -> state
val leave_loop : Frama_c_kernel.Cil_types.stmt -> state -> state
val relate : Frama_c_kernel.Cil_types.kernel_function -> Frama_c_kernel.Base.Hptset.t -> t -> Frama_c_kernel.Base.SetLattice.t
relate kf bases state
returns the set of bases bases
in relation with bases
in state
— i.e. all bases other than bases
whose value may affect the properties inferred on bases
in state
. state
is the initial state of an analysis of kf
. For a non-relational domain, it is always safe to return empty
. For a relational domain, it is always safe to return top
, but it disables MemExec.
val filter : [ `Pre of Frama_c_kernel.Cil_types.kernel_function | `Post of Frama_c_kernel.Cil_types.kernel_function | `Print ] -> Frama_c_kernel.Base.Hptset.t -> t -> t
filter kind bases states
reduces the state state
to only keep properties about bases
— it is a projection on the set of bases
. It allows reusing an analysis of kf
from an initial state pre
to a final state post
. If kind
is `Pre kf
, state
is the initial state of function kf
, and bases
includes all inputs of kf
and satisfies relate kf bases state = bases
. If kind
is `Post kf
, state
is the final state of kf
, and bases
includes all inputs and outputs of kf
. Afterwards, the two resulting states reduced_pre
and reduced_post
are used as follow: when kf
should be analyzed with the initial state s
, if filter kf `Pre s = reduced_pre
, then the analysis is skipped, and reuse kf s reduced_post
is used as its final state instead. If kind
is `Print
, the state is reduced before printing it for the end-user.
val reuse : Frama_c_kernel.Cil_types.kernel_function -> Frama_c_kernel.Base.Hptset.t -> current_input:t -> previous_output:t -> t
reuse kf bases current_input previous_output
merges the initial state current_input
with a final state previous_output
from a previous analysis of kf
started with an equivalent initial state. reuse
must overwrite the properties on bases
in current_input
with the ones in previous_output
. Properties on other bases must be left unchanged from current_input
.
Domain_builtin.Complete
provides the simplest implementation of filter
and reuse
, which is: let filter _ _ _ state = state let reuse _ _ ~current_input:_ ~previous_output = previous_output This is correct as the cache will be triggered only for an initial state exactly equal to the previous initial state, in which case the previous output state is indeed a correct final state on its own.
Category for the messages about the domain. Created by Domain_builder.Complete
using the domain name.
val post_analysis : t Eva.Eval.or_bottom -> unit
This function is called after the analysis. The argument is the state computed at the return statement of the main function. The function can also access all states stored in the Store module during the analysis. If the analysis aborted, this function is not called. Defined by Domain_builder.Complete
as doing nothing.
module Store : sig ... end
Storage of the states computed by the analysis. Automatically built by Domain_builder.Complete
.
val structure : t Eva__.Abstract.Domain.structure
val get : 'a Eva__.Structure.Key_Domain.key -> (t -> 'a) option
For a key of type k key
:
- if the values of type
t
contain a subpart of typek
from a module identified by the key, thenget key
returns an accessor for it. - otherwise,
get key
returns None.
For a key of type k key
:
- if the values of type
t
contain a subpart of typek
from a module identified by the key, thenset key v t
returns the valuet
in which this subpart has been replaced byv
. - otherwise,
set key _
is the identity function.
Iterators on the components of a structure.
val iter : polymorphic_iter_fun -> t -> unit
val fold : 'b polymorphic_fold_fun -> t -> 'b -> 'b
val map : polymorphic_map_fun -> t -> t