method vexpr (e:exp) = begin
let with_succ v = [v ; Ival.Widen_Hints.V.succ v]
and with_pred v = [Ival.Widen_Hints.V.pred v ; v ]
and with_s_p_ v = [Ival.Widen_Hints.V.pred v; v; Ival.Widen_Hints.V.succ v]
and default_visit e =
match Cil.isInteger e with
| Some _int64 ->
Cil.SkipChildren
| _ ->
Cil.DoChildren
and comparison_visit add1 add2 e1 e2 =
let add key set =
let hints =
List.fold_right
Ival.Widen_Hints.add
set
Ival.Widen_Hints.empty
in
widen_hints :=
Widen_type.add_num_hints
None (Widen_type.VarKey key) hints !widen_hints
in
begin
let e1,e2 = Cil.constFold true e1, Cil.constFold true e2 in
match (Cil.isInteger e1, Cil.isInteger e2, e1, e2) with
| Some int64, _,
_, {enode=(CastE(_, { enode=Lval (Var varinfo, _)})
| Lval (Var varinfo, _))}->
add
(Base.create_varinfo varinfo)
(add1 int64);
Cil.SkipChildren
| _, Some int64,
{enode=(CastE(_, { enode=Lval (Var varinfo, _)})
| Lval (Var varinfo, _))}, _ ->
add
(Base.create_varinfo varinfo)
(add2 int64);
Cil.SkipChildren
| _ ->
Cil.DoChildren
end
in
match e.enode with
| BinOp (Lt, e1, e2, _)
| BinOp (Gt, e2, e1, _)
| BinOp (Le, e2, e1, _)
| BinOp (Ge, e1, e2, _) ->
comparison_visit with_succ with_pred e1 e2
| BinOp (Eq, e1, e2, _)
| BinOp (Ne, e1, e2, _) ->
comparison_visit with_s_p_ with_s_p_ e1 e2
| _ -> default_visit e
end