@ -260,7 +260,7 @@ module Val = struct
; itv_updated_by = ItvUpdatedBy . Top
; modeled_range = ModeledRange . bottom
; taint = Taint . bottom
; powloc = ( if is_int then PowLoc . bot tom else PowLoc . unknown )
; powloc = ( if is_int then PowLoc . bot else PowLoc . unknown )
; arrayblk = ( if is_int then ArrayBlk . bottom else ArrayBlk . unknown )
; traces }
@ -484,7 +484,7 @@ module Val = struct
Itv . is_bottom pruned_itv
&& ( not ( Itv . is_bottom x . itv ) )
&& Itv . is_bottom y . itv
&& not ( PowLoc . is_bot tom ( get_all_locs y ) )
&& not ( PowLoc . is_bot ( get_all_locs y ) )
then x . itv
else pruned_itv
in
@ -929,12 +929,22 @@ module MemPure = struct
(* * Collect the location that was increased by one, i.e., [x -> x+1] *)
let get_incr_locs m =
fold ( fun l v acc -> if MVal . is_incr_of l v then PowLoc . add l acc else acc ) m PowLoc . empty
fold ( fun l v acc -> if MVal . is_incr_of l v then PowLoc . add l acc else acc ) m PowLoc . bot
let find_opt l m = Option . map ( find_opt l m ) ~ f : MVal . get_val
let add ? ( represents_multiple_values = false ) l v m =
let add ? ( represents_multiple_values = false ) l ( { Val . powloc ; arrayblk } as v ) m =
let v =
if Loc . is_unknown l then
(* We do not add the other locations except the unknown itself in its value. This spoiled
other values raising out of memory sometimes , rather than being helpful for analysis
precision . * )
{ v with
Val . powloc = ( if PowLoc . is_bot powloc then powloc else PowLoc . unknown )
; arrayblk = ( if ArrayBlk . is_bottom arrayblk then arrayblk else ArrayBlk . unknown ) }
else v
in
let f = function
| None ->
Some ( represents_multiple_values | | Loc . represents_multiple_values l , v )
@ -1030,7 +1040,7 @@ module AliasTarget = struct
| IteratorOffset { java_tmp = None }
| IteratorHasNext { java_tmp = None }
| Top ->
PowLoc . empty
PowLoc . bot
let use_loc l x = PowLoc . mem l ( get_locs x )
@ -2093,7 +2103,7 @@ module MemReach = struct
let add_iterator_alias_common ~ cond ~ alias_add id m =
let locs =
let accum_loc l v acc = if cond v then PowLoc . add l acc else acc in
MemPure . fold accum_loc m . mem_pure PowLoc . empty
MemPure . fold accum_loc m . mem_pure PowLoc . bot
in
{ m with alias = alias_add id locs m . alias }
@ -2260,29 +2270,29 @@ module MemReach = struct
let set_latest_prune : LatestPrune . t -> t -> t = fun latest_prune x -> { x with latest_prune }
let get_reachable_locs_from_aux : f : ( Pvar . t -> bool ) -> Pow Loc. t -> _ t0 -> Pow Loc. t =
let get_reachable_locs_from_aux : f : ( Pvar . t -> bool ) -> LocSet . t -> _ t0 -> LocSet . t =
let add_reachable1 ~ root loc v acc =
if Loc . equal root loc then Pow Loc. union acc ( Val . get_all_locs v )
else if Loc . is_field_of ~ loc : root ~ field_loc : loc then Pow Loc. add loc acc
if Loc . equal root loc then LocSet . union acc ( Val . get_all_locs v | > PowLoc . to_set )
else if Loc . is_field_of ~ loc : root ~ field_loc : loc then LocSet . add loc acc
else acc
in
let rec add_from_locs heap locs acc = Pow Loc. fold ( add_from_loc heap ) locs acc
let rec add_from_locs heap locs acc = LocSet . fold ( add_from_loc heap ) locs acc
and add_from_loc heap loc acc =
if Pow Loc. mem loc acc then acc
if LocSet . mem loc acc then acc
else
let reachable_locs = MemPure . fold ( add_reachable1 ~ root : loc ) heap Pow Loc. empty in
add_from_locs heap reachable_locs ( Pow Loc. add loc acc )
let reachable_locs = MemPure . fold ( add_reachable1 ~ root : loc ) heap LocSet . empty in
add_from_locs heap reachable_locs ( LocSet . add loc acc )
in
let add_param_locs ~ f mem acc =
let add_loc loc _ acc = if Loc . exists_pvar ~ f loc then Pow Loc. add loc acc else acc in
let add_loc loc _ acc = if Loc . exists_pvar ~ f loc then LocSet . add loc acc else acc in
MemPure . fold add_loc mem acc
in
fun ~ f locs m ->
let locs = add_param_locs ~ f m . mem_pure locs in
add_from_locs m . mem_pure locs Pow Loc. empty
add_from_locs m . mem_pure locs LocSet . empty
let get_reachable_locs_from : ( Pvar . t * Typ . t ) list -> Pow Loc. t -> _ t0 -> Pow Loc. t =
let get_reachable_locs_from : ( Pvar . t * Typ . t ) list -> LocSet . t -> _ t0 -> LocSet . t =
fun formals locs m ->
let is_formal pvar = List . exists formals ~ f : ( fun ( formal , _ ) -> Pvar . equal pvar formal ) in
get_reachable_locs_from_aux ~ f : is_formal locs m
@ -2304,9 +2314,9 @@ module MemReach = struct
Pvar . is_return pvar | | Pvar . is_global pvar
| | List . exists formals ~ f : ( fun ( formal , _ ) -> Pvar . equal formal pvar )
in
get_reachable_locs_from_aux ~ f Pow Loc. empty m
get_reachable_locs_from_aux ~ f LocSet . empty m
in
fun l -> Pow Loc. mem l reachable_locs
fun l -> LocSet . mem l reachable_locs
in
let stack_locs = StackLocs . filter is_reachable m . stack_locs in
let mem_pure = MemPure . filter ( fun l _ -> is_reachable l ) m . mem_pure in
@ -2536,9 +2546,9 @@ module Mem = struct
let strong_update : PowLoc . t -> Val . t -> t -> t = fun p v -> map ~ f : ( MemReach . strong_update p v )
let get_reachable_locs_from : ( Pvar . t * Typ . t ) list -> Pow Loc. t -> _ t0 -> Pow Loc. t =
let get_reachable_locs_from : ( Pvar . t * Typ . t ) list -> LocSet . t -> _ t0 -> LocSet . t =
fun formals locs ->
f_lift_default ~ default : Pow Loc. empty ( MemReach . get_reachable_locs_from formals locs )
f_lift_default ~ default : LocSet . empty ( MemReach . get_reachable_locs_from formals locs )
let update_mem : PowLoc . t -> Val . t -> t -> t = fun ploc v -> map ~ f : ( MemReach . update_mem ploc v )