let frama_c_memcpy state actuals =
try
match actuals with
| [exp_dst,dst,_; exp_src,src,_ ; exp_size,size,_] ->
let size = Cvalue_type.V.project_ival size in
let min,max = Ival.min_and_max size in
let min = match min with
| None -> Int.zero
| Some m -> Int.max m Int.zero
and max = match max with
| None -> assert false
| Some m -> m
in
let size_min = Int.mul Int.eight min in
let right = loc_bytes_to_loc_bits src in
let left = loc_bytes_to_loc_bits dst in
let right_loc = make_loc right (Int_Base.inject size_min) in
let term_size = Logic_utils.expr_to_term ~cast:true exp_size in
let array_src = Logic_utils.array_with_range exp_src term_size
and array_dst = Logic_utils.array_with_range exp_dst term_size
in
CilE.set_syntactic_context (CilE.SyMemLogic array_src);
begin
match Relations_type.Model.copy_offsetmap
~with_alarms:(warn_all_quiet_mode ())
right_loc
state
with
| None ->
None,
Relations_type.Model.bottom,
Location_Bits.Top_Param.bottom
| Some offsetmap ->
CilE.set_syntactic_context (CilE.SyMemLogic array_dst);
let new_state =
Relations_type.Model.paste_offsetmap
offsetmap left Int.zero size_min state
in
let fuzz = Int.sub max min in
if Int.is_zero fuzz
then None, new_state, Location_Bits.get_bases right
else
let fuzz = Int.mul Int.eight fuzz in
let fuzz = Int_Base.inject fuzz in
let ival_min = Ival.inject_singleton size_min in
let left = Location_Bits.location_shift ival_min left in
let right = Location_Bits.location_shift ival_min right in
CilE.set_syntactic_context (CilE.SyMemLogic array_src);
let garb =
Relations_type.Model.find
~conflate_bottom:false
~with_alarms:(warn_all_quiet_mode ())
state
(make_loc right fuzz)
in
CilE.set_syntactic_context (CilE.SyMemLogic array_dst);
let new_state =
Relations_type.Model.add_binding
~exact:false
~with_alarms:(warn_all_quiet_mode ())
new_state
(make_loc left fuzz)
garb
in
None, new_state, Location_Bits.get_bases right
end
| _ ->
raise Db.Value.Aborted
with
V.Not_based_on_null | Lmap.Cannot_copy | Db.Value.Aborted ->
Value_parameters.error
"Invalid call to Frama_C_memcpy%a"
pretty_actuals
actuals;
do_degenerate None;
raise Db.Value.Aborted