@ -29,30 +29,30 @@ struct
trace : trace ;
id : string }
[ @@ deriving compare ]
and trace = Intra of Typ . Procname . t
and trace = Intra of Typ . Procname . t
| Inter of Typ . Procname . t * Typ . Procname . t * Location . t
[ @@ deriving compare ]
[ @@ deriving compare ]
and astate = t
and astate = t
let set_size_pos : t -> t
let set_size_pos : t -> t
= fun c ->
if Itv . Bound . lt ( Itv . lb c . size ) Itv . Bound . zero
then { c with size = Itv . make Itv . Bound . zero ( Itv . ub c . size ) }
else c
let string_of_location : Location . t -> string
let string_of_location : Location . t -> string
= fun loc ->
let fname = SourceFile . to_string loc . Location . file in
let pos = Location . to_string loc in
F . fprintf F . str_formatter " %s:%s " fname pos ;
F . flush_str_formatter ()
let pp_location : F . formatter -> t -> unit
let pp_location : F . formatter -> t -> unit
= fun fmt c ->
F . fprintf fmt " %s " ( string_of_location c . loc )
let pp : F . formatter -> t -> unit
let pp : F . formatter -> t -> unit
= fun fmt c ->
let c = set_size_pos c in
if Config . bo_debug < = 1 then
@ -65,30 +65,31 @@ let pp : F.formatter -> t -> unit
Itv . pp c . idx Itv . pp c . size pp_location c pname ( string_of_location loc )
| Intra _ -> F . fprintf fmt " %a < %a at %a " Itv . pp c . idx Itv . pp c . size pp_location c
let get_location : t -> Location . t
let get_location : t -> Location . t
= fun c -> c . loc
let get_trace : t -> trace
let get_trace : t -> trace
= fun c -> c . trace
let get_proc_name : t -> Typ . Procname . t
let get_proc_name : t -> Typ . Procname . t
= fun c -> c . proc_name
let make : Typ . Procname . t -> Location . t -> string -> idx : Itv . t -> size : Itv . t -> t
let make : Typ . Procname . t -> Location . t -> string -> idx : Itv . t -> size : Itv . t -> t
= fun proc_name loc id ~ idx ~ size ->
{ proc_name ; idx ; size ; loc ; id ; trace = Intra proc_name }
let filter1 : t -> bool
let filter1 : t -> bool
= fun c ->
Itv . eq c . idx Itv . top | | Itv . eq c . size Itv . top
| | Itv . Bound . eq ( Itv . lb c . idx ) Itv . Bound . MInf
| | Itv . Bound . eq ( Itv . lb c . size ) Itv . Bound . MInf
| | ( Itv . eq c . idx Itv . nat && Itv . eq c . size Itv . nat )
let filter2 : t -> bool
let filter2 : t -> bool
= fun c ->
( not ( Itv . is_finite c . idx ) | | not ( Itv . is_finite c . size ) ) (* basically, alarms involving infinity are filtered *)
&& (* except the following cases: *)
(* basically, alarms involving infinity are filtered *)
( not ( Itv . is_finite c . idx ) | | not ( Itv . is_finite c . size ) )
&& (* except the following cases *)
not ( ( Itv . Bound . is_not_infty ( Itv . lb c . idx ) && (* idx non-infty lb < 0 *)
Itv . Bound . lt ( Itv . lb c . idx ) Itv . Bound . zero )
| |
@ -104,8 +105,8 @@ let filter2 : t -> bool
( Itv . Bound . is_not_infty ( Itv . ub c . idx ) && (* idx non-infty ub > size ub *)
( Itv . Bound . gt ( Itv . ub c . idx ) ( Itv . ub c . size ) ) ) )
(* check buffer overrun and return its confidence *)
let check : t -> string option
(* check buffer overrun and return its confidence *)
let check : t -> string option
= fun c ->
(* idx = [il, iu], size = [sl, su], we want to check that 0 <= idx < size *)
let c' = set_size_pos c in (* if sl < 0, use sl' = 0 *)
@ -135,10 +136,10 @@ let check : t -> string option
else
Some Localise . BucketLevel . b2
let invalid : t -> bool
let invalid : t -> bool
= fun x -> Itv . invalid x . idx | | Itv . invalid x . size
let to_string : t -> string
let to_string : t -> string
= fun c ->
let c = set_size_pos c in
" Offset: " ^ Itv . to_string c . idx ^ " Size: " ^ Itv . to_string c . size
@ -149,7 +150,7 @@ let to_string : t -> string
^ MF . monospaced_to_string ( Typ . Procname . to_string pname ^ " () " ) ^ " "
| Intra _ -> " " )
let subst : t -> Itv . Bound . t Itv . SubstMap . t -> Typ . Procname . t -> Typ . Procname . t -> Location . t -> t
let subst : t -> Itv . Bound . t Itv . SubstMap . t -> Typ . Procname . t -> Typ . Procname . t -> Location . t -> t
= fun c subst_map caller_pname callee_pname loc ->
if Itv . is_symbolic c . idx | | Itv . is_symbolic c . size then
{ c with idx = Itv . subst c . idx subst_map ;
@ -277,6 +278,9 @@ struct
let of_int : int -> t
= fun n -> { bot with itv = Itv . of_int n }
let of_itv : Itv . t -> t
= fun itv -> { bot with itv }
let of_pow_loc : PowLoc . t -> t
= fun x -> { bot with powloc = x }
@ -496,7 +500,7 @@ struct
let find : Loc . t -> astate -> Val . t
= fun l m ->
try find l m with
| Not_found -> Val . bot
| Not_found -> Val . top_itv
let find_set : PowLoc . t -> astate -> Val . t
= fun locs mem ->
@ -545,10 +549,10 @@ struct
match M . find k rhs with
| v' -> Pvar . equal v v'
| exception Not_found -> false
in
M . for_all is_in_rhs lhs
in
M . for_all is_in_rhs lhs
let join : t -> t -> t
let join : t -> t -> t
= fun x y ->
let join_v _ v1_opt v2_opt =
match v1_opt , v2_opt with
@ -559,10 +563,10 @@ struct
in
M . merge join_v x y
let widen : prev : t -> next : t -> num_iters : int -> t
let widen : prev : t -> next : t -> num_iters : int -> t
= fun ~ prev ~ next ~ num_iters : _ -> join prev next
let pp : F . formatter -> t -> unit
let pp : F . formatter -> t -> unit
= fun fmt x ->
let pp_sep fmt () = F . fprintf fmt " , @, " in
let pp1 fmt ( k , v ) =
@ -574,19 +578,19 @@ struct
F . fprintf fmt " }@] " ;
F . fprintf fmt " @] "
let load : Ident . t -> Exp . t -> t -> t
let load : Ident . t -> Exp . t -> t -> t
= fun id exp m ->
match exp with
| Exp . Lvar x -> M . add id x m
| _ -> m
let store : Exp . t -> Exp . t -> t -> t
let store : Exp . t -> Exp . t -> t -> t
= fun e _ m ->
match e with
| Exp . Lvar x -> M . filter ( fun _ y -> not ( Pvar . equal x y ) ) m
| _ -> m
let find : Ident . t -> t -> Pvar . t option
let find : Ident . t -> t -> Pvar . t option
= fun k m -> try Some ( M . find k m ) with Not_found -> None
end