Module Pulselib.PulseOperations

type t = PulseDomainInterface.AbductiveDomain.t
type 'a access_result = ('aPulseBasicInterface.Diagnostic.t * t) IStdlib.IStd.result
val ok_continue : t -> (PulseDomainInterface.ExecutionDomain.t list'a) IStdlib.IStd.result
val check_addr_access : IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t access_result

Check that the address is not known to be invalid

module Closures : sig ... end
val eval : IBase.Location.t -> IR.Exp.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) access_result

Use the stack and heap to evaluate the given expression down to an abstract address representing its value.

Return an error state if it traverses some known invalid address or if the end destination is known to be invalid.

val prune : IBase.Location.t -> condition:IR.Exp.t -> t -> t access_result
val eval_deref : IBase.Location.t -> IR.Exp.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) access_result

Like eval but evaluates *exp.

val eval_access : IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> Pulselib.PulseDomainInterface.BaseMemory.Access.t -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) access_result

Like eval but starts from an address instead of an expression, checks that it is valid, and if so dereferences it according to the access.

val havoc_id : IR.Ident.t -> PulseBasicInterface.ValueHistory.t -> t -> t
val havoc_field : IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> IR.Fieldname.t -> PulseBasicInterface.ValueHistory.t -> t -> t access_result
val realloc_pvar : IR.Pvar.t -> IBase.Location.t -> t -> t
val write_id : IR.Ident.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t
val write_field : IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> IR.Fieldname.t -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t access_result

write the edge ref --.field--> obj

val write_arr_index : IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> index:PulseBasicInterface.AbstractValue.t -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t access_result

write the edge ref[index]--> obj

val write_deref : IBase.Location.t -> ref:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> obj:(PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t access_result

write the edge ref --*--> obj

val invalidate : IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t access_result

record that the address is invalid

val allocate : IR.Procname.t -> IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t
val add_dynamic_type : IR.Typ.Name.t -> PulseBasicInterface.AbstractValue.t -> t -> t
val remove_allocation_attr : PulseBasicInterface.AbstractValue.t -> t -> t
val invalidate_access : IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> Pulselib.PulseDomainInterface.BaseMemory.Access.t -> t -> t access_result

record that what the address points via the access to is invalid

val invalidate_array_elements : IBase.Location.t -> PulseBasicInterface.Invalidation.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> t access_result

record that all the array elements that address points to is invalid

val shallow_copy : IBase.Location.t -> (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) -> t -> (t * (PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t)) access_result

returns the address of a new cell with the same edges as the original

val get_dynamic_type_unreachable_values : IR.Var.t list -> t -> (IR.Var.t * IR.Typ.Name.t) list

Given a list of variables, computes the unreachable values if the variables were removed from the stack, then return the dynamic types of those values if they are available

val remove_vars : IR.Var.t list -> IBase.Location.t -> t -> t access_result
val check_address_escape : IBase.Location.t -> IR.Procdesc.t -> PulseBasicInterface.AbstractValue.t -> PulseBasicInterface.ValueHistory.t -> t -> t access_result
val call : caller_proc_desc:IR.Procdesc.t -> callee_data:(IR.Procdesc.t * PulseSummary.t) option -> IBase.Location.t -> IR.Procname.t -> ret:(IR.Ident.t * IR.Typ.t) -> actuals:((PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) * IR.Typ.t) list -> formals_opt:(IR.Pvar.t * IR.Typ.t) list option -> t -> PulseDomainInterface.ExecutionDomain.t list access_result

perform an interprocedural call: apply the summary for the call proc name passed as argument if it exists

val unknown_call : IBase.Location.t -> PulseBasicInterface.CallEvent.t -> ret:(IR.Ident.t * IR.Typ.t) -> actuals:((PulseBasicInterface.AbstractValue.t * PulseBasicInterface.ValueHistory.t) * IR.Typ.t) list -> formals_opt:(IR.Pvar.t * IR.Typ.t) list option -> t -> t

performs a call to a function with no summary by optimistically havoc'ing the by-ref actuals and the return value as appropriate