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 =
Current_table.find_superposition current_table return
in
let init_state =
Current_table.find_superposition
current_table
(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
(State_imp.to_set init_state)
(State_imp.to_set 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;
let ret_val =
(match return with
| Kstmt {skind = Return (Some ({enode = Lval lv}),_)} ->
offsetmap_of_lv ~with_alarms:(warn_all_quiet_mode ()) state lv
| Kstmt {skind = Return (None,_)} -> None
| _ -> assert false)
in
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
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
result