let scope env vars sc wp =
on_context env "scope" wp Keep_opened Keep_assigns
(fun env assigns p ->
let frame = L.get_frame env in
let wp = WpModel.local_scope frame vars sc p in
begin
match assigns , sc with
| EffectAssigns a , (Mcfg.SC_Block_in | Mcfg.SC_Function_frame) ->
let m = WpModel.mem_at frame Clabels.Here in
let zs =
List.fold_left
(fun zs x ->
let te = Ctypes.object_of x.vtype in
let ax = D.Aloc(te,WpModel.cvar m x) in
let zx = WpModel.dzone_assigned ax in
WpModel.dzone_union zs zx)
(F.var a.a_locals) vars
in
D.subst a.a_locals zs wp
| RegionAssigns r ,
(Mcfg.SC_Block_out | Mcfg.SC_Function_out) when vars <> [] ->
begin
let m = WpModel.mem_at frame Clabels.Here in
let region =
List.fold_left
(fun r x ->
let lx = WpModel.cvar m x in
let tx = Ctypes.object_of x.vtype in
let rx = WpModel.region_assigned (D.Aloc(tx,lx)) in
WpModel.region_union r rx)
(WpModel.region_empty()) vars in
let pool = D.pool () in
let xs,bindings,local = WpModel.region_fingerprint pool region in
r.r_locals <- (vars,xs,local) :: r.r_locals ;
F.p_and bindings wp
end
| RegionAssigns r ,
(Mcfg.SC_Block_in | Mcfg.SC_Function_frame) when vars <> [] ->
begin
match r.r_locals with
| (xvars,xs,_) :: stack ->
if xvars != vars then
Wp_parameters.fatal ~current:true
"Expected locals %a instead of %a"
pp_vars vars pp_vars xvars ;
r.r_locals <- stack ;
D.forall xs wp
| [] ->
Wp_parameters.fatal ~current:true
"No opened block for locals %a" pp_vars vars
end
| _ -> wp
end)