let do_assign ~with_alarms old_state lv exp =
if true then do_assign ~with_alarms old_state lv exp
else
let vars =
get_influential_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 =
Cvalue.Model.find
~conflate_bottom:true
~with_alarms:CilE.warn_none_mode
old_state
v
in
if Location_Bytes.is_included value Location_Bytes.top_float
then raise Too_linear;
ignore (Cvalue.V.splitting_cardinal_less_than
~split_non_enumerable:42 value 142);
let treat_subdiv subvalue acc =
let sub_oldstate =
Cvalue.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
Cvalue.Model.join acc sub_newstate
in
Location_Bytes.fold_enum
~split_non_enumerable:42
treat_subdiv
value
Cvalue.Model.bottom
with
| Not_less_than | Too_linear -> try_sub tail
| Location_Bytes.Error_Top -> assert false;
in
try_sub vars