let do_assign ~with_alarms old_state lv exp =
if true then do_assign ~with_alarms old_state lv exp
else
let vars = (get_vars ~with_alarms:CilE.warn_none_mode old_state exp) in
let rec try_sub vars =
match vars with
[] | [ _ ] ->
do_assign ~with_alarms old_state lv exp
| v :: tail ->
try
if not (List.exists (fun x -> Locations.loc_equal v x) tail)
then raise Too_linear;
let value =
Relations_type.Model.find
~with_alarms:CilE.warn_none_mode
old_state
v
in
if Cvalue_type.V.cardinal_zero_or_one value
|| Locations.Location_Bytes.is_included value Locations.Location_Bytes.top_float
then raise Too_linear;
ignore (Cvalue_type.V.splitting_cardinal_less_than
~split_non_enumerable:42 value 142);
Value_parameters.debug "subdiv assignment: candidate %a value %a@."
Locations.pretty v
Cvalue_type.V.pretty value;
let treat_subdiv subvalue acc =
let sub_oldstate =
Relations_type.Model.add_binding
~with_alarms:CilE.warn_none_mode
~exact:true
old_state
v
subvalue
in
let sub_newstate =
do_assign ~with_alarms sub_oldstate lv exp
in
Relations_type.Model.join acc sub_newstate
in
Location_Bytes.fold_enum
~split_non_enumerable:42
treat_subdiv
value
Relations_type.Model.bottom
with
Not_less_than | Too_linear ->
try_sub tail
| Location_Bytes.Error_Top ->
assert false;
in
try_sub vars