IR.Sil
The Smallfoot Intermediate Language
val pp_if_kind : F.formatter -> if_kind -> unit
val is_terminated_if_kind : if_kind -> bool
Whether an if_kind
has a true
terminated
field, meaning that the conditional control flow creates a temporary branching in the CFG of the procedure that is closed by a Join
node containing an EndBranches
instruction. Frontends should try to terminate conditionals (by setting the terminated
flag and emitting an EndBranches
instruction at the appropriate point) whenever possible so some analyses can detect which instructions are executed under the influence of a conditional more easily.
type instr_metadata =
| Abstract of IBase.Location.t
a good place to apply abstraction, mostly used in the biabduction analysis
*)| CatchEntry of {
try_id : int;
loc : IBase.Location.t;
}
entry of C++ catch blocks
*)| EndBranches
the end of a conditional control flow generated by an if
statement whose if_kind
satisfies is_terminated_if_kind
| ExitScope of Var.t list * IBase.Location.t
remove temporaries and dead program variables
*)| Nullify of Pvar.t * IBase.Location.t
nullify stack variable
*)| Skip
no-op
*)| TryEntry of {
try_id : int;
loc : IBase.Location.t;
}
entry of C++ try block
*)| TryExit of {
try_id : int;
loc : IBase.Location.t;
}
exit of C++ try block
*)| VariableLifetimeBegins of {
pvar : Pvar.t;
typ : Typ.t;
loc : IBase.Location.t;
is_cpp_structured_binding : bool;
}
stack variable declared
*)val compare_instr_metadata : instr_metadata -> instr_metadata -> int
type instr =
| Load of {
id : Ident.t;
e : Exp.t;
typ : Typ.t;
loc : IBase.Location.t;
}
Load a value from the heap into an identifier.
id = *e:typ
where
e
is an expression denoting a heap addresstyp
is the type of *e
and id
.| Store of {
e1 : Exp.t;
typ : Typ.t;
e2 : Exp.t;
loc : IBase.Location.t;
}
Store the value of an expression into the heap.
*e1:typ = e2
where
e1
is an expression denoting a heap addresstyp
is the type of *e1
and e2
.| Prune of Exp.t * IBase.Location.t * bool * if_kind
The semantics of Prune (exp, loc, is_then_branch, if_kind)
is that it prunes the state (blocks, or diverges) if exp
evaluates to 1
; the boolean is_then_branch
is true
if this is the then
branch of an if
condition, false
otherwise (it is meaningless if if_kind
is not Ik_if
, Ik_bexp
, or other if
-like cases
This instruction, together with the CFG structure, is used to encode control-flow with tests in the source program such as if
branches and while
loops.
| Call of Ident.t * Typ.t
* Exp.t
* (Exp.t * Typ.t) list
* IBase.Location.t
* CallFlags.t
Call ((ret_id, ret_typ), e_fun, arg_ts, loc, call_flags)
represents an instruction ret_id = e_fun(arg_ts)
| Metadata of instr_metadata
hints about the program that are not strictly needed to understand its semantics, for instance information about its original syntactic structure
*)An instruction. Syntactic invariants of instructions per-frontend are documented in Checkers.SilValidation
, where Clang is the most general validator (that is, it properly subsumes all other validators). These invariants are enforced when --sil-validation is passed.
Compare instructions from different procedures without considering loc
s, ident
s, pvar
s, or try_id
s. The exp_map
parameter gives a mapping of names used in the first instr
to those used in the second, and the returned exp_map
includes any additional mappings inferred from this comparison.
val skip_instr : instr
val instr_is_auxiliary : instr -> bool
Check if an instruction is auxiliary, or if it comes from source instructions.
val location_of_instr : instr -> IBase.Location.t
Get the location of the instruction
val pp_instr_metadata : IStdlib.Pp.env -> F.formatter -> instr_metadata -> unit
val pp_instr :
print_types:bool ->
IStdlib.Pp.env ->
F.formatter ->
instr ->
unit
Pretty print an instruction.
val d_instr : instr -> unit
Dump an instruction.