let eval_binop_int ~with_alarms ?typ ~te1 ev1 op ev2 =
match op with
| PlusPI | IndexPI -> V.add_untyped (osizeof_pointed te1) ev1 ev2
| MinusPI -> V.add_untyped (Int_Base.neg (osizeof_pointed te1)) ev1 ev2
| PlusA -> V.add_untyped (Int_Base.one) ev1 ev2
| MinusA -> V.add_untyped Int_Base.minus_one ev1 ev2
| MinusPP ->
let minus_val = V.add_untyped Int_Base.minus_one ev1 ev2 in
begin
try
let size = Int_Base.project (sizeof_pointed te1) in
let size = Int.div size Int.eight in
if Int.is_one size then
minus_val
else
let minus_val = Cvalue.V.project_ival minus_val in
Cvalue.V.inject_ival (Ival.scale_div ~pos:true size minus_val)
with
| Int_Base.Error_Top
| Cvalue.V.Not_based_on_null
| Not_found ->
V.join (V.topify_arith_origin ev1) (V.topify_arith_origin ev2)
end
| Mod -> V.c_rem ~with_alarms ev1 ev2
| Div -> V.div ~with_alarms ev1 ev2
| Mult -> V.arithmetic_function ~with_alarms "*" Ival.mul ev1 ev2
| LOr ->
assert false
| LAnd ->
assert false
| BXor ->
V.oper_on_values ~with_alarms "^" Int.logxor ev1 ev2
| BOr ->
V.bitwise_or ~size:(bitsSizeOf te1) ev1 ev2
| BAnd ->
(try
let size = bitsSizeOf te1 in
let signed = is_signed_int_enum_pointer te1 in
V.bitwise_and ~size ~signed ev1 ev2
with SizeOfError _ ->
V.join (V.topify_arith_origin ev1) (V.topify_arith_origin ev2))
| Eq | Ne | Ge | Le | Gt | Lt ->
let warn, ev1, ev2 = check_comparable op ev1 ev2 in
if warn then CilE.warn_pointer_comparison with_alarms;
if warn && Value_parameters.UndefinedPointerComparisonPropagateAll.get ()
then V.zero_or_one
else
let signed = is_signed_int_enum_pointer (unrollType te1) in
let f = match op with
| Eq -> V.check_equal true
| Ne -> V.check_equal false
| Ge -> V.comparisons ">=" ~signed V.do_ge
| Le -> V.comparisons "<=" ~signed V.do_le
| Gt -> V.comparisons ">" ~signed V.do_gt
| Lt -> V.comparisons "<" ~signed V.do_lt
| _ -> assert false
in
f ev1 ev2
| Shiftrt | Shiftlt ->
begin
let f =
if op = Shiftlt then V.shift_left else V.shift_right
in
try
let size = Extlib.opt_map bitsSizeOf typ in
f ~with_alarms ?size ev1 ev2
with SizeOfError _ -> assert false
end