let doEdge s succ d =
let kinstr = Kstmt s in
let states = (d.value) in
let annots_after, _specs =
Annotations.single_fold_stmt
(fun annot (annot_after,spec as acc) ->
match annot with
| Before
(User { annot_content = AStmtSpec spec' }
| AI (_,{annot_content = AStmtSpec spec' }) )
->
let spec = match spec with
| None -> spec'
| Some s -> Logic_utils.merge_funspec s spec'; s
in
(annot_after, Some spec)
| After
(User { annot_content = AStmtSpec _spec' }
| AI (_,{annot_content = AStmtSpec _spec' }) ) ->
CilE.warn_once
"Ignoring statement contract rooted after statement";
acc
| After (AI (_, a) | User a) -> a :: annot_after, spec
| Before _ -> acc)
s
([], None)
in
CilE.start_stmt kinstr;
let states =
List.fold_left
(fun acc annot -> interp_annot acc s annot)
states
annots_after
in
if (not (Db.Value.Record_Value_After_Callbacks.is_empty ())) &&
(store_state_after_during_dataflow s succ)
then (
let old =
try Cil_datatype.Stmt.Hashtbl.find states_after s
with Not_found -> Relations_type.Model.bottom
in
let updated = State_set.fold Relations_type.Model.join states old in
Cil_datatype.Stmt.Hashtbl.replace states_after s updated
);
let states =
match Kernel_function.blocks_closed_by_edge s succ with
| [] -> states
| closed_blocks ->
let block_top_addresses_of_locals =
block_top_addresses_of_locals closed_blocks
in
State_set.fold
(fun state set ->
let state =
Relations_type.Model.uninitialize_locals closed_blocks state
in
State_set.add (block_top_addresses_of_locals state) set)
states
State_set.empty;
in
CilE.end_stmt ();
{ d with value = states }