let compute_using_prototype_for_state state kf =
match kf.fundec with
| Definition _ -> assert false
| Declaration (_, varinfo, _,_) ->
let behaviors = !Value.valid_behaviors kf state in
let assigns = Ast_info.merge_assigns behaviors in
let return_deps,deps =
match assigns with
[] ->
Lmap_bitwise.From_Model.LOffset.empty,
Lmap_bitwise.From_Model.empty
| assigns ->
let (rt_typ,_,_,_) = splitFunctionTypeVI varinfo in
let input_zone ins =
match ins with
[] -> Zone.top
| l ->
(try
List.fold_left
(fun acc loc ->
List.fold_left
(fun acc lv ->
Zone.join acc
(!Value.lval_to_zone_state state lv))
acc
(match loc with
Location loc ->
!Properties.Interp.loc_to_lval
loc.it_content
| Nothing -> []
))
Zone.bottom l
with Invalid_argument "not an lvalue" ->
From_parameters.result ~once:true ~current:true
"Unable to extract precise FROM in %a"
Kernel_function.pretty_name kf;
Zone.top)
in
let treat_assign acc (out, ins) =
try
List.fold_left
(fun acc lv ->
let output_zone =
try
!Value.lval_to_zone_state state lv
with Invalid_argument "not an lvalue" ->
From_parameters.result ~once:true ~current:true
"Unable to extract assigns in %a"
Kernel_function.pretty_name kf;
Zone.top
in
Lmap_bitwise.From_Model.add_binding ~exact:true
acc output_zone (input_zone ins))
acc
(match out with
Location out ->
!Properties.Interp.loc_to_lval out.it_content
| Nothing -> []
)
with Invalid_argument "not an lvalue" ->
From_parameters.result ~once:true ~current:true "Unable to extract assigns in %a"
Kernel_function.pretty_name kf;
acc
in
let treat_ret_assign acc (out,ins) =
try
let coffs = match out with
Location out ->
!Properties.Interp.loc_to_offset out.it_content
| Nothing -> []
in
List.fold_left
(fun acc coff ->
let (base,width) = bitsOffset rt_typ coff in
Lmap_bitwise.From_Model.LOffset.add_iset
~exact:true
(Abstract_value.Int_Intervals.from_ival_size
(Ival.of_int base)
(Int_Base.inject (Int.of_int width)))
(input_zone ins) acc)
acc coffs
with Invalid_argument "not an lvalue" | SizeOfError _ ->
From_parameters.result ~once:true ~current:true
"Unable to extract a proper offset. Using FROM for the whole \\result";
Lmap_bitwise.From_Model.LOffset.add_iset ~exact:false
(Abstract_value.Int_Intervals.from_ival_size
(Ival.of_int 0) (Bit_utils.sizeof rt_typ))
(input_zone ins) acc
in
let return_assigns, other_assigns =
List.fold_left
(fun (ra,oa as res) (x,_ as a) ->
match x with
Location loc ->
if Logic_utils.is_result loc.it_content
then a::ra,oa else ra,a::oa
| Nothing -> res
)
([],[]) assigns
in
(List.fold_left treat_ret_assign
Lmap_bitwise.From_Model.LOffset.empty return_assigns,
List.fold_left
treat_assign
Lmap_bitwise.From_Model.empty
other_assigns)
in
{ deps_return = return_deps; Function_Froms.deps_table = deps }