let copy_offsetmap_from_virtual ~with_alarms
loc1 lv2 loc2 (state:Relations_type.Model.t) =
if (not (Int_Base.equal loc1.size loc2.size))
|| (try
ignore
(Location_Bits.cardinal_less_than loc2.loc
(Value_parameters.ArrayPrecisionLevel.get ()));
false
with Not_less_than -> true)
then begin
raise Lmap.Cannot_copy
end;
let target_offset = snd lv2 in
let target_size =
try Int_Base.project loc2.size
with Int_Base.Error_Top -> raise Lmap.Cannot_copy
in
let result_relations =
match fst lv2 with
| Mem({enode = Lval slv} as e) when UseRelations.get () ->
let sub_left_loc = lval_to_loc ~with_alarms state slv in
begin try
let _, _, target_offset =
try
eval_offset ~reduce_valid_index:(Parameters.SafeArrays.get ())
~with_alarms None (typeOf e) state target_offset
with Offset_not_based_on_Null _ -> raise Lmap.Cannot_copy
in
let offsetmap =
Relations_type.Model.copy_from_virtual
sub_left_loc target_offset target_size state
in
offsetmap
with Relations_type.Use_Main_Memory ->
Cvalue_type.V_Offsetmap.empty
end
| Mem({enode = BinOp((PlusPI|IndexPI|MinusPI as op),
{enode = Lval slv},e2,_)} as e)
when UseRelations.get () ->
let typ = typeOf e in
let e2 = eval_expr ~with_alarms state e2 in
begin try
let ival = (Cvalue_type.V.project_ival e2) in
let ival = if op=MinusPI then Ival.neg ival else ival in
let ival = Ival.scale
(Int_Base.project (sizeof_pointed typ))
ival
in
let sub_left_loc = lval_to_loc ~with_alarms state slv in
let _, _, target_offset = eval_offset
~reduce_valid_index:(Parameters.SafeArrays.get ())
~with_alarms None typ state target_offset in
let target_offset = Ival.add target_offset ival in
let offsetmap =
Relations_type.Model.copy_from_virtual
sub_left_loc target_offset target_size state
in
offsetmap
with Relations_type.Use_Main_Memory | Cvalue_type.V.Not_based_on_null ->
Cvalue_type.V_Offsetmap.empty
end
| _ ->
Cvalue_type.V_Offsetmap.empty
in
result_relations