Skip to content

Commit b84844b

Browse files
committed
CongruenceDomain.sub: Handle case precisely where two signed numbers are subtracted and do not produce an overflow.
1 parent 958b827 commit b84844b

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

src/cdomain/value/cdomains/int/congruenceDomain.ml

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -139,21 +139,21 @@ struct
139139

140140
let of_congruence ik (c,m) = normalize ik @@ Some(c,m)
141141

142-
let of_bitfield ik (z,o) =
142+
let of_bitfield ik (z,o) =
143143
match BitfieldDomain.Bitfield.to_int (z,o) with
144144
| Some x -> normalize ik (Some (x, Z.zero))
145145
| _ ->
146146
(* get posiiton of first top bit *)
147-
let tl_zeros = Z.trailing_zeros (Z.logand z o) in
148-
let ik_bits = Size.bit ik in
149-
let m = if tl_zeros > ik_bits then Z.one else Z.pow Z.one tl_zeros in
150-
let c = Z.logand o (m -: Z.one) in
147+
let tl_zeros = Z.trailing_zeros (Z.logand z o) in
148+
let ik_bits = Size.bit ik in
149+
let m = if tl_zeros > ik_bits then Z.one else Z.pow Z.one tl_zeros in
150+
let c = Z.logand o (m -: Z.one) in
151151
normalize ik (Some (c, m))
152152

153-
let to_bitfield ik x =
154-
let x = normalize ik x in
155-
match x with
156-
| None -> (Z.zero, Z.zero)
153+
let to_bitfield ik x =
154+
let x = normalize ik x in
155+
match x with
156+
| None -> (Z.zero, Z.zero)
157157
| Some (c,m) -> BitfieldDomain.Bitfield.of_congruence ik (c,m)
158158

159159
let maximal t = match t with
@@ -347,11 +347,18 @@ struct
347347
raise (ArithmeticOnIntegerBot (Printf.sprintf "%s op %s" (show x) (show y)))
348348
| Some a, Some b when no_ov ->
349349
normalize ik (Some (no_ov_case a b))
350-
| Some (c1, m1), Some (c2, m2) when m1 =: Z.zero && m2 =: Z.zero && not (Cil.isSigned ik) ->
351-
let _, max_ik = range ik in
350+
| Some (c1, m1), Some (c2, m2) when m1 =: Z.zero && m2 =: Z.zero ->
351+
let min_ik, max_ik = range ik in
352352
let m_ikind = max_ik +: Z.one in
353-
let c = (c1 -: c2 +: m_ikind) %: m_ikind in
354-
Some(c, Z.zero)
353+
if Cil.isSigned ik then
354+
let c = c1 -: c2 in
355+
if c >=: min_ik then
356+
Some (c, Z.zero)
357+
else
358+
top_of ik
359+
else
360+
let c = (c1 -: c2 +: m_ikind) %: m_ikind in
361+
Some (c, Z.zero)
355362
| Some a, Some b when not (Cil.isSigned ik) ->
356363
handle_overflow ik (no_ov_case a b)
357364
| _ -> top ()
@@ -523,8 +530,8 @@ struct
523530

524531
let refine_with_congruence ik a b = meet ik a b
525532

526-
let refine_with_bitfield ik a (z,o) =
527-
let a = normalize ik a in
533+
let refine_with_bitfield ik a (z,o) =
534+
let a = normalize ik a in
528535
meet ik a (of_bitfield ik (z,o))
529536

530537
let refine_with_excl_list ik a b = a

0 commit comments

Comments
 (0)