Skip to content

Commit 3e1ddb4

Browse files
committed
Hacky fix for issue #1803
1 parent b817c3c commit 3e1ddb4

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,13 +294,23 @@ struct
294294
| None, _ | _, None -> raise (ArithmeticOnIntegerBot (Printf.sprintf "%s op %s" (show x) (show y)))
295295
| (Some (x1,x2) as x), (Some (y1,y2) as y) ->
296296
begin
297-
let is_zero v = Ints_t.compare v Ints_t.zero = 0 in
297+
let (r, ov) =
298+
try
299+
binary_op_with_norm IArith.div ik x y
300+
with Division_by_zero ->
301+
(top_of ik, {underflow=false; overflow=false})
302+
in
303+
if leq (of_int ik (Ints_t.zero) |> fst) (Some (y1,y2)) then
304+
(top_of ik, ov)
305+
else
306+
(r, ov)
307+
(* let is_zero v = Ints_t.compare v Ints_t.zero = 0 in
298308
match y1, y2 with
299309
| l, u when is_zero l && is_zero u -> (top_of ik,{underflow=false; overflow=false})
300310
| l, _ when is_zero l -> div ik (Some (x1,x2)) (Some (Ints_t.one,y2))
301311
| _, u when is_zero u -> div ik (Some (x1,x2)) (Some (y1, Ints_t.(neg one)))
302-
| _ when leq (of_int ik (Ints_t.zero) |> fst) (Some (y1,y2)) -> (top_of ik,{underflow=false; overflow=false})
303-
| _ -> binary_op_with_norm IArith.div ik x y
312+
(* | _ when leq (of_int ik (Ints_t.zero) |> fst) (Some (y1,y2)) -> (top_of ik,{underflow=false; overflow=false}) *)
313+
| _ -> binary_op_with_norm IArith.div ik x y *)
304314
end
305315

306316
let ne ik x y =

src/cdomain/value/cdomains/intDomain0.ml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,36 @@ module IntervalArith (Ints_t : IntOps.IntOps) = struct
372372
let x2y2p = (Ints_t.div x2 y2) in
373373
(min4 x1y1n x1y2n x2y1n x2y2n, max4 x1y1p x1y2p x2y1p x2y2p)
374374

375+
let rec div (a, b) (c, d) =
376+
(* let open Ints_t in *)
377+
assert Ints_t.(compare c d <= 0);
378+
if Ints_t.(compare one c) <= 0 then
379+
Ints_t.(min (div a c) (div a d), max (div b c) (div b d))
380+
else if Ints_t.(compare d zero) < 0 then
381+
Ints_t.(min (div b c) (div b d), max (div a c) (div a d))
382+
else (
383+
let p =
384+
if Ints_t.(compare one d) <= 0 then
385+
Some (div (a, b) (Ints_t.one, d))
386+
else
387+
None
388+
in
389+
let n =
390+
if Ints_t.(compare c zero) < 0 then
391+
Some (div (a, b) (c, Ints_t.(neg one)))
392+
else
393+
None
394+
in
395+
match p, n with
396+
| Some (p1, p2), Some (n1, n2) -> Ints_t.(min p1 n1, max p2 n2)
397+
| Some x, None
398+
| None, Some x -> x
399+
| None, None -> raise Division_by_zero
400+
(* let (p1, p2) = div (a, b) (Ints_t.one, d) in
401+
let (n1, n2) = div (a, b) (c, Ints_t.(neg one)) in
402+
Ints_t.(min p1 n1, max p2 n2) *)
403+
)
404+
375405
let add (x1, x2) (y1, y2) = (Ints_t.add x1 y1, Ints_t.add x2 y2)
376406
let sub (x1, x2) (y1, y2) = (Ints_t.sub x1 y2, Ints_t.sub x2 y1)
377407

tests/regression/39-signed-overflows/15-div-minus-1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ int main() {
55
int bad = INT_MIN / -1; // WARN
66
int x, y;
77
if (y != 0) {
8-
bad = x / y; // TODO WARN
8+
bad = x / y; // WARN
99
}
1010
return 0;
1111
}

0 commit comments

Comments
 (0)