@@ -266,7 +266,15 @@ struct
266266 let ur = if Int64. compare max_int x2 = 0 then y2 else x2 in
267267 norm @@ Some (lr,ur)
268268
269+ (* Returns top if one of a, b is top, otherwise return result *)
270+ let on_top_return_top_bin a b result =
271+ if is_top a || is_top b then top () else result
272+
273+ let on_top_return_top_un a result =
274+ if is_top a then top () else result
275+
269276 let log f i1 i2 =
277+ on_top_return_top_bin i1 i2 @@
270278 match is_bot i1, is_bot i2 with
271279 | true , true -> bot ()
272280 | true , _
@@ -280,6 +288,7 @@ struct
280288 let logand = log (&& )
281289
282290 let log1 f i1 =
291+ on_top_return_top_un i1 @@
283292 if is_bot i1 then
284293 bot ()
285294 else
@@ -290,6 +299,7 @@ struct
290299 let lognot = log1 not
291300
292301 let bit f i1 i2 =
302+ on_top_return_top_bin i1 i2 @@
293303 match is_bot i1, is_bot i2 with
294304 | true , true -> bot ()
295305 | true , _
@@ -315,17 +325,20 @@ struct
315325 let shift_right = bit (fun x y -> Int64. shift_right x (Int64. to_int y))
316326 let shift_left = bit (fun x y -> Int64. shift_left x (Int64. to_int y))
317327
318- let neg = function None -> None | Some (x ,y ) -> norm @@ Some (Int64. neg y, Int64. neg x)
328+ let neg x = on_top_return_top_un x @@ match x with None -> None | Some (x ,y ) -> norm @@ Some (Int64. neg y, Int64. neg x)
319329
320330 let add x y =
331+ on_top_return_top_bin x y @@
321332 match x, y with
322333 | None , None -> None
323334 | None , _ | _ , None -> raise (ArithmeticOnIntegerBot (Printf. sprintf " %s op %s" (short 80 x) (short 80 y)))
324335 | Some (x1 ,x2 ), Some (y1 ,y2 ) -> norm @@ Some (Int64. add x1 y1, Int64. add x2 y2)
325336
326337 let sub i1 i2 = add i1 (neg i2)
327338
328- let rem x y = match x, y with
339+ let rem x y =
340+ on_top_return_top_bin x y @@
341+ match x, y with
329342 | None , None -> None
330343 | None , _ | _ , None -> raise (ArithmeticOnIntegerBot (Printf. sprintf " %s op %s" (short 80 x) (short 80 y)))
331344 | Some (xl , xu ), Some (yl , yu ) ->
@@ -348,6 +361,7 @@ struct
348361 meet (bit Int64. rem x y) range
349362
350363 let mul x y =
364+ on_top_return_top_bin x y @@
351365 match x, y with
352366 | None , None -> bot ()
353367 | None , _ | _ , None -> raise (ArithmeticOnIntegerBot (Printf. sprintf " %s op %s" (short 80 x) (short 80 y)))
@@ -358,6 +372,7 @@ struct
358372 (max (max x1y1 x1y2) (max x2y1 x2y2)))
359373
360374 let rec div x y =
375+ on_top_return_top_bin x y @@
361376 match x, y with
362377 | None , None -> bot ()
363378 | None , _ | _ , None -> raise (ArithmeticOnIntegerBot (Printf. sprintf " %s op %s" (short 80 x) (short 80 y)))
0 commit comments