package goblint
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=452d8491527aea21f2cbb11defcc14ba0daf9fdb6bdb9fc0af73e56eac57b916
sha512=1993cd45c4c7fe124ca6e157f07d17ec50fab5611b270a434ed1b7fb2910aa85a8e6eaaa77dad770430710aafb2f6d676c774dd33942d921f23e2f9854486551
doc/goblint.lib/Goblint_lib/Base/MainFunctor/index.html
Module Base.MainFunctor
Parameters
module Priv : BasePriv.Smodule RVEval : BaseDomain.ExpEvaluator with type t = BaseComponents(Priv.D).tSignature
include module type of struct include Analyses.DefaultSpec end
module P = Analyses.UnitPval asm : ('a, 'b, 'c, 'd) Analyses.ctx -> 'aval skip : ('a, 'b, 'c, 'd) Analyses.ctx -> 'aval paths_as_set : ('a, 'b, 'c, 'd) Analyses.ctx -> 'a listmodule A = Analyses.UnitAmodule Dom : sig ... endtype t = Dom.tmodule D = Dommodule V : sig ... endmodule G : sig ... endtype extra = (GoblintCil.varinfo * Offs.t * bool) listtype store = D.ttype value = VD.ttype address = AD.tval startstate : 'a -> storeval exitstate : 'a -> storeval is_privglob : GoblintCil.varinfo -> boolmodule VarH : sig ... endmodule VarMap : sig ... endval array_map : GoblintCil.attributes VarMap.t VarH.t reftype marshal = GoblintCil.attributes VarMap.t VarH.tval add_to_array_map :
GoblintCil.fundec ->
(GoblintCil.varinfo * VD.t) list ->
unitval attributes_varinfo :
VarMap.key ->
GoblintCil.fundec ->
(GoblintCil.attributes * GoblintCil.attribute list) optionval project_val :
ValueDomain.VDQ.t ->
(GoblintCil.attributes * GoblintCil.attributes) option ->
PrecisionUtil.int_precision option ->
VD.t ->
bool ->
VD.tval project :
ValueDomain.VDQ.t ->
PrecisionUtil.int_precision option ->
CPA.t ->
GoblintCil.fundec ->
CPA.tval heap_var : bool -> ('a, 'b, 'c, 'd) Analyses.ctx -> Basetype.Variables.tval char_array : (GoblintCil.lval, Batteries.bytes) Batteries.Hashtbl.tval init : GoblintCil.attributes VarMap.t VarH.t option -> unitval finalize : unit -> GoblintCil.attributes VarMap.t VarH.tval unop_ID : GoblintCil.unop -> ID.t -> ID.tval unop_FD : GoblintCil.unop -> FD.t -> valueval evalunop : GoblintCil.unop -> GoblintCil.Cil.typ -> value -> valueval binop_ID : GoblintCil.Cil.ikind -> GoblintCil.binop -> ID.t -> ID.t -> ID.tval binop_FD : GoblintCil.Cil.fkind -> GoblintCil.binop -> FD.t -> FD.t -> FD.tval int_returning_binop_FD : GoblintCil.binop -> FD.t -> FD.t -> ID.tval is_int_returning_binop_FD : GoblintCil.binop -> boolval evalbinop_base :
ctx:('a, 'b, 'c, 'd) Analyses.ctx ->
GoblintCil.binop ->
GoblintCil.typ ->
value ->
GoblintCil.typ ->
value ->
GoblintCil.typ ->
valueval add_offset_varinfo : Addr.Offs.t -> Addr.t -> Addr.tval sync' :
[ `Init
| `Join
| `JoinCall of CilType.Fundec.t
| `Normal
| `Return
| `Thread ] ->
(BaseDomain.BaseComponents(Priv.D).t,
[> `Bot | `Lifted1 of Priv.G.t ],
'a,
[> `Left of Priv.V.t ])
Analyses.ctx ->
D.tval sync :
(BaseDomain.BaseComponents(Priv.D).t,
[> `Bot | `Lifted1 of Priv.G.t ],
'a,
[> `Left of Priv.V.t ])
Analyses.ctx ->
[< `Init
| `Join
| `JoinCall of CilType.Fundec.t
| `Normal
| `Return
| `Thread ] ->
D.tval publish_all :
(BaseDomain.BaseComponents(Priv.D).t,
[> `Bot | `Lifted1 of Priv.G.t ],
'a,
[> `Left of Priv.V.t ])
Analyses.ctx ->
[ `Init
| `Join
| `JoinCall of CilType.Fundec.t
| `Normal
| `Return
| `Thread ] ->
unitval get_var :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.varinfo ->
valueval get :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
?top:VD.t ->
?full:bool ->
store ->
address ->
GoblintCil.exp option ->
valueget st addr returns the value corresponding to addr in st * adding proper dependencies. * For the exp argument it is always ok to put None. This means not using precise information about * which part of an array is involved.
val reachable_from_value :
Queries.ask ->
value ->
GoblintCil.typ ->
string ->
AD.tval context : 'a -> GoblintCil.fundec -> store -> storeval reachable_top_pointers_types :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
AD.t ->
Queries.TS.tval eval_rv_ask_evalint :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
VD.tEvaluate expression using EvalInt query. Base itself also answers EvalInt, so recursion goes indirectly through queries. This allows every subexpression to also meet more precise value from other analyses. Non-integer expression just delegate to next eval_rv function.
val eval_rv_no_ask_evalint :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
valueEvaluate expression without EvalInt query on outermost expression. This is used by base responding to EvalInt to immediately directly avoid EvalInt query cycle, which would return top. Recursive eval_rv calls on subexpressions still go through eval_rv_ask_evalint.
val eval_rv_back_up :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
valueval eval_rv_base :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
valueEvaluate expression structurally by base. This handles constants directly and variables using CPA. Subexpressions delegate to eval_rv, which may use queries on them.
val eval_rv_base_lval :
eval_lv:
(ctx:
('a,
[> `Bot | `Lifted1 of Priv.G.t ] as 'b,
'c,
[> `Left of Priv.V.t ] as 'd)
Analyses.ctx ->
store ->
GoblintCil.lval ->
AD.t) ->
ctx:('a, 'b, 'c, 'd) Analyses.ctx ->
store ->
GoblintCil.exp ->
GoblintCil.lval ->
valueval evalbinop :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.binop ->
e1:GoblintCil.exp ->
?t1:GoblintCil.typ ->
e2:GoblintCil.exp ->
?t2:GoblintCil.typ ->
GoblintCil.typ ->
valueval evalbinop_mustbeequal :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.binop ->
e1:GoblintCil.exp ->
?t1:GoblintCil.typ ->
e2:GoblintCil.exp ->
?t2:GoblintCil.typ ->
GoblintCil.typ ->
valueEvaluate BinOp using MustBeEqual query as fallback.
val eval_fv :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
AD.tval eval_tv :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
AD.tval eval_int :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
ValueDomain.ID.tval convert_offset :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.offset ->
VD.offsval eval_lv :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.lval ->
AD.tval eval_rv_keep_bot :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
valueval eval_rv :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
valueval query_evalint :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
[> `Bot | `Lifted of ValueDomain.ID.t | `Top ]val eval_exp : store -> GoblintCil.exp -> ValueDomain.ID.int_t optionval eval_funvar :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
GoblintCil.exp ->
ValueDomain.AD.tval eval_rv_address :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp ->
VD.tEvaluate expression as address. Avoids expensive Apron EvalInt if the Int result would be useless to us anyway.
val is_not_alloc_var :
('a, 'b, 'c, 'd) Analyses.ctx ->
GoblintCil.varinfo ->
boolval is_not_heap_alloc_var :
('a, 'b, 'c, 'd) Analyses.ctx ->
GoblintCil.varinfo ->
boolval query_invariant :
(Priv.D.t BaseDomain.basecomponents_t,
[> `Bot | `Lifted1 of Priv.G.t ],
'a,
[> `Left of Priv.V.t ])
Analyses.ctx ->
Invariant.context ->
Invariant.tval query_invariant_global :
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
[< `Left of Priv.V.t | `Right of 'c ] ->
Invariant.tval exp_may_signed_overflow :
('a, 'b, 'c, 'd) Analyses.ctx ->
GoblintCil.exp ->
BoolDomain.MayBool.tThis query returns false if the expression exp will definitely not result in an overflow.
Each subexpression is analyzed to see if an overflow happened. For each operator in the expression, we use the query EvalInt to approximate the bounds of each operand and we compute if in the worst case there could be an overflow.
For now we return true if the expression contains a shift left.
val lval_may_signed_overflow :
('a, 'b, 'c, 'd) Analyses.ctx ->
GoblintCil.lval ->
BoolDomain.MayBool.tval update_variable :
GoblintCil.varinfo ->
GoblintCil.typ ->
CPA.value ->
CPA.t ->
CPA.tval add_partitioning_dependencies :
GoblintCil.varinfo ->
VD.t ->
store ->
storeAdd dependencies between a value and the expression it (or any of its contents) are partitioned by
val set :
ctx:
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
?invariant:bool ->
?blob_destructive:bool ->
?lval_raw:GoblintCil.lval ->
?rval_raw:GoblintCil.exp ->
?t_override:GoblintCil.Cil.typ ->
store ->
AD.t ->
GoblintCil.Cil.typ ->
value ->
storeset st addr val returns a state where addr is set to val * it is always ok to put None for lval_raw and rval_raw, this amounts to not using/maintaining * precise information about arrays.
val set_many :
ctx:
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
(AD.t * GoblintCil.Cil.typ * value) list ->
storeval rem_many : 'a -> store -> GoblintCil.varinfo list -> storeval rem_many_partitioning :
ValueDomain.VDQ.t ->
store ->
GoblintCil.varinfo list ->
storeval is_some_bot : value -> boolmodule InvariantEval : sig ... endmodule Invariant : sig ... endval invariant :
(InvariantEval.D.t, InvariantEval.G.t, 'a, InvariantEval.V.t) Analyses.ctx ->
InvariantEval.D.t ->
GoblintCil.exp ->
bool ->
InvariantEval.D.tval set_savetop :
ctx:
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
?lval_raw:GoblintCil.lval ->
?rval_raw:GoblintCil.exp ->
store ->
AD.t ->
GoblintCil.typ ->
VD.t ->
storeval assign :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
GoblintCil.lval ->
GoblintCil.exp ->
storeval branch :
(store, InvariantEval.G.t, 'a, InvariantEval.V.t) Analyses.ctx ->
GoblintCil.exp ->
bool ->
storeval body :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
GoblintCil.fundec ->
storeval return :
(store,
[> `Bot | `Lifted1 of Priv.G.t | `Lifted2 of VD.t ],
'a,
[> `Left of Priv.V.t | `Right of ThreadIdDomain.Thread.t ])
Analyses.ctx ->
GoblintCil.exp option ->
GoblintCil.fundec ->
storeval vdecl :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
GoblintCil.varinfo ->
storeval collect_funargs :
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
?warn:bool ->
store ->
GoblintCil.exp list ->
address listFrom a list of expressions, collect a list of addresses that they might point to, or contain pointers to.
val collect_invalidate :
deep:bool ->
ctx:
('a, [> `Bot | `Lifted1 of Priv.G.t ], 'b, [> `Left of Priv.V.t ])
Analyses.ctx ->
?warn:bool ->
store ->
GoblintCil.exp list ->
address listval invalidate :
must:bool ->
?deep:bool ->
ctx:
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
store ->
GoblintCil.exp list ->
storeval make_entry :
?thread:bool ->
(D.t, G.t, C.t, V.t) Analyses.ctx ->
GoblintCil.fundec ->
GoblintCil.exp list ->
D.tval enter :
(D.t, G.t, C.t, V.t) Analyses.ctx ->
'a ->
GoblintCil.fundec ->
GoblintCil.exp list ->
(D.t * D.t) listval forkfun :
(D.t, G.t, C.t, V.t) Analyses.ctx ->
GoblintCil.lval option ->
GoblintCil.varinfo ->
GoblintCil.exp list ->
(GoblintCil.lval option * GoblintCil.varinfo * GoblintCil.exp list * bool)
listval assert_fn :
(InvariantEval.D.t, InvariantEval.G.t, 'a, InvariantEval.V.t) Analyses.ctx ->
GoblintCil.exp ->
bool ->
InvariantEval.D.tval special_unknown_invalidate :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
CilType.Varinfo.t ->
LibraryDesc.Cil.Cil.exp list ->
storeval check_invalid_mem_dealloc :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
GoblintCil.varinfo ->
GoblintCil.exp ->
unitval points_to_heap_only :
('a, 'b, 'c, 'd) Analyses.ctx ->
GoblintCil.exp ->
boolval get_size_of_ptr_target :
('a, 'b, 'c, 'd) Analyses.ctx ->
GoblintCil.exp ->
ValueDomainQueries.ID.t Queries.resultval special :
(store, G.t, C.t, V.t) Analyses.ctx ->
GoblintCil.lval option ->
GoblintCil.varinfo ->
GoblintCil.exp list ->
storeval combine_env :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
'b ->
'c ->
GoblintCil.fundec ->
'd ->
'e ->
D.t ->
Queries.ask ->
Priv.D.t Goblint_lib__BaseDomain.basecomponents_tval combine_assign :
(store, [> `Bot | `Lifted1 of Priv.G.t ], 'a, [> `Left of Priv.V.t ])
Analyses.ctx ->
GoblintCil.lval option ->
'b ->
GoblintCil.fundec ->
GoblintCil.exp list ->
'c ->
D.t ->
Q.ask ->
D.tval threadenter :
(D.t, G.t, C.t, V.t) Analyses.ctx ->
multiple:'a ->
GoblintCil.lval option ->
GoblintCil.varinfo ->
GoblintCil.exp list ->
D.t listval threadspawn :
(BaseDomain.BaseComponents(Priv.D).t,
[> `Bot | `Lifted1 of Priv.G.t ],
'a,
[> `Left of Priv.V.t ])
Analyses.ctx ->
multiple:'b ->
GoblintCil.lval option ->
GoblintCil.varinfo ->
GoblintCil.exp list ->
('c, 'd, 'e, 'f) Analyses.ctx ->
D.tval unassume :
(D.t,
[ `Bot | `Lifted1 of Priv.G.t | `Lifted2 of VD.t | `Top ],
'a,
[ `Left of Priv.V.t | `Right of ThreadIdDomain.thread ])
Analyses.ctx ->
GoblintCil.exp ->
WideningTokenLifter.TS.elt list ->
D.tval event :
(store, InvariantEval.G.t, 'a, InvariantEval.V.t) Analyses.ctx ->
Events.t ->
'b ->
BaseDomain.BaseComponents(Priv.D).t