let doInstr stmt (i: instr) (d: t) =
!Db.progress ();
CilE.start_stmt (Kstmt stmt);
let d_states = d.value in
let unreachable = State_set.is_empty d_states in
let result =
if unreachable then
Dataflow.Done d
else begin
let apply_each_state f =
let modified_states =
State_set.fold
(fun acc state_value -> State_set.add (f state_value) acc)
State_set.empty
d_states
in
Dataflow.Done { counter_unroll = 0; value = modified_states }
in
match i with
| Set (lv,exp,_loc) ->
apply_each_state
(fun state_value ->
do_assign
~with_alarms:(warn_all_quiet_mode ())
state_value
lv
exp)
| Call (lval_to_assign,
{enode = Lval (Var {vname=("__builtin_va_start"|"__builtin_va_arg"|"__builtin_va_end" as _builtin_name) },NoOffset)},
[{enode = Lval lv}],_loc) ->
apply_each_state
(fun state ->
let state =
do_assign_abstract_value
~with_alarms:(warn_all_quiet_mode ())
state
lv
Cvalue.V.top_int
in
( match lval_to_assign with
None -> state
| Some lval_assign ->
do_assign_abstract_value
~with_alarms:(warn_all_quiet_mode ())
state
lval_assign
Cvalue.V.top_int))
| Call (lval_to_assign,funcexp,argl,_loc) ->
Dataflow.Done
{ counter_unroll = 0;
value = interp_call stmt lval_to_assign funcexp argl d_states}
| Asm _ ->
warning_once_current
"assuming assembly code has no effects in function %t"
pretty_current_cfunction_name;
Dataflow.Default
| Skip _ ->
Dataflow.Default
| Code_annot (_,_) ->
Dataflow.Default
end
in
CilE.end_stmt ();
result