let get_multsubadd_unsigned_assertion
~simplify_constants:simplify_constants
~warning:warning
full_expr op expr1 expr2 =
let t = Cil.typeOf full_expr in
let size = bitsSizeOf t
in if (size > 32) then (
rte_warn "bitsSize of %a > 32: not treated" d_exp full_expr ;
[]
)
else
let (minType,maxType) = (Int64.zero, get_unsigned_max size) in
let full_add_term () =
let term1 = translate_C_expr_to_term ~cast:false expr1
and term2 = translate_C_expr_to_term ~cast:false expr2
in Logic_const.term (TBinOp (op, term1,term2)) (Ctype t)
in let assertion () =
if op = MinusA then
assertion_ge (full_add_term ()) minType
else
assertion_le (full_add_term ()) maxType
in
if simplify_constants then (
match get_expr_val expr1, get_expr_val expr2 with
| Some a64, Some b64 ->
let big_a64 = Int.of_int64 a64
and big_b64 = Int.of_int64 b64
in
if op = MinusA then
let big_diff = Int.sub big_a64 big_b64
in if Int.compare big_diff (Int.of_int64 minType) < 0 then
let assertion = assertion () in
if warning then
rte_warn
"unsigned overflow assert broken: %a"
d_predicate_named assertion
;
[ (assertion, Some (make_check_false ())) ]
else [ ]
else if op = PlusA then
let big_add = Int.add big_a64 big_b64
in if Int.compare big_add (Int.of_int64 maxType) > 0 then
let assertion = assertion () in
if warning then
rte_warn
"unsigned overflow assert broken: %a"
d_predicate_named assertion
;
[ (assertion, Some (make_check_false ())) ]
else [ ]
else (
assert(op = Mult) ;
let big_mult = Int.mul big_a64 big_b64
in let () = assert(Int.compare big_mult Int.zero >= 0)
in let b_ov = (Int.compare big_mult (Int.of_int64 maxType) > 0)
in
if b_ov then
let assertion = assertion () in
if warning then
rte_warn
"unsigned overflow assert broken: %a"
d_predicate_named assertion
;
[ (assertion, Some (make_check_false ())) ]
else [ ]
)
| Some a64, None
| None, Some a64 ->
if op = Mult then (
if (Int64.compare a64 Int64.zero = 0) ||
(Int64.compare a64 Int64.one = 0)
then []
else [ (assertion (), None) ]
) else [ (assertion (), None) ]
| None,None -> [ (assertion (), None) ]
) else [ (assertion (), None) ]