method vstmt stm =
let findf_in_pl f (pl : (int * int) list) =
List.filter (fun (fst,_snd) ->
if fst = f then true else false)
pl
in
let check_incdec vi e =
if IH.mem idDefHash vi.vid then
let pl = IH.find idDefHash vi.vid in
match findf_in_pl stm.sid pl with (_sid,redefid)::_l ->
let rhso = getDefRhs redefid in
(match rhso with
None -> (if !debug then (Cilmsg.debug "check_incdec: couldn't find rhs for def %d" redefid);
false)
| Some(rhs, _, _indiosh) ->
(match rhs with
RD.RDCall _ -> (if !debug then Cilmsg.debug "check_incdec: rhs not an expression";
false)
| RD.RDExp e' ->
if compareExp e e' then true
else (if !debug then Cilmsg.debug "check_incdec: rhs of %d: %a, and needed redef %a not equal"
redefid d_plainexp e' d_plainexp e;
false)))
| [] -> (if !debug then Cilmsg.debug "check_incdec: current statement not in list: %d. %s = %a"
stm.sid
vi.vname
d_exp e;
false)
else (if !debug then Cilmsg.debug "check_incdec: %s not in idDefHash"
vi.vname;
false)
in
let will_be_call e =
match e.enode with
Lval(Var vi,NoOffset) ->
if not(IH.mem iioh vi.vid) then false
else (match IH.find iioh vi.vid with
None -> false | Some _ -> true)
| _ -> false
in
let good_instr i =
match i with
Set((Var(vi),_),e,_) ->
if will_be_call e &&
not(List.mem vi cur_func.slocals)
then cur_func.slocals <- vi::cur_func.slocals;
is_volatile vi ||
(not (UD.VS.mem vi unused_set) &&
not (IH.mem incdecHash vi.vid) &&
not (check_incdec vi e)) ||
will_be_call e
| Call (Some(Var(vi),_),_,_,_) ->
not (IH.mem iioh vi.vid) ||
(match IH.find iioh vi.vid with
None -> true | Some _ -> false)
| Asm(_,_,slvlst,_,_,_) ->
List.iter (fun (_,_s,lv) ->
match lv with (Var vi,_) ->
if List.mem vi cur_func.slocals
then ()
else cur_func.slocals <- vi::cur_func.slocals
|_ -> ()) slvlst;
true
| _ -> true
in
let call_fixer i =
match i with
Call (Some(Var(vi),_),e,el,l) as c ->
if UD.VS.mem vi unused_set then
Call(None,e,el,l)
else c
| _ -> i
in
match stm.skind with
Instr il ->
stm.skind <-
Instr (if good_instr il then call_fixer il
else Skip Cil_datatype.Location.unknown);
SkipChildren
| _ -> DoChildren