let cached_substitute call_site_froms extra_loc subst =
let f k intervs =
match k with
| Base.Var( vi,_)
| Base.Initialized_Var ( vi,_)->
( try
( match VarinfoHashtbl.find subst vi
with
Froms f -> f
| Lvalue offs ->
(Lmap_bitwise.From_Model.LOffset.find_intervs
(Zone.default k)
intervs
offs))
with
Not_found ->
Lmap_bitwise.From_Model.find call_site_froms (Zone.inject k intervs) )
| Base.Null | Base.String _ | Base.Cell_class _ ->
Zone.inject k intervs
in
let joiner = Zone.join in
let projection base =
match Base.validity base with
| Base.Known (min_valid,max_valid) | Base.Unknown (min_valid,max_valid)->
Int_Intervals.inject_bounds min_valid max_valid
| Base.All -> assert false
in
let zone_substitution =
Zone.cached_fold ~cache:("from substitution", 331)
~f ~joiner ~empty:Zone.bottom ~projection
in
let zone_substitution x =
try
zone_substitution x
with Zone.Error_Top -> Zone.top
in
fun z -> Zone.join extra_loc (zone_substitution z)