let externalize return kf =
match kf.fundec with
| Declaration _ -> assert false
| Definition (fundec,_loc) ->
assert
(StmtStartData.iter
(fun k v ->
if State_set.is_empty !(v.value)
then ()
else (Value_parameters.fatal "sid:%d@\n%a@\n"
k
State_set.pretty !(v.value)));
true);
let superpos = (find_current return).superposition in
let init_state =
find_current (Kstmt (Kernel_function.find_first_stmt kf))
in
let superpos =
let result =
match return with
| Kstmt {skind = Return (Some ({enode = Lval (Var v,_)}),_)} ->
Some v
| _ -> None
in
check_fct_postconditions ~result
kf
init_state.superposition
superpos
Normal
in
let state = State_set.join_dropping_relations superpos in
Value_parameters.feedback "Recording results for %a"
Kernel_function.pretty_name kf;
merge_current ~degenerate:false;
Value_parameters.debug "Recording results phase 1";
let ret_val =
(match return with
| Kstmt {skind = Return (Some ({enode = Lval lv}),_)} ->
CilE.set_syntactic_context (CilE.SyMem lv);
let loc_to_read =
lval_to_loc ~with_alarms:(warn_all_quiet_mode ()) state lv
in
let result =
try
Relations_type.Model.copy_offsetmap loc_to_read state
with Lmap.Cannot_copy ->
assert false
in
result
| Kstmt {skind = Return (None,_)} -> None
| _ -> assert false)
in
Value_parameters.debug "Recording results phase 2";
let state =
Relations_type.Model.clear_state_from_locals fundec state
in
let offsetmap_top_addresses_of_locals, state_top_addresses_of_locals =
top_addresses_of_locals fundec
in
Value_parameters.debug "Recording results phase 3";
let result =
(match ret_val with
| None -> ret_val
| Some ret_val ->
let r,warn = offsetmap_top_addresses_of_locals ret_val
in
if warn then warn_locals_escape_result fundec;
Some r),
state_top_addresses_of_locals state,
!bases_containing_locals
in
Value_parameters.debug "Recording results phase 4";
result