diff --git a/infer/src/IR/IntLit.ml b/infer/src/IR/IntLit.ml index 85d316344..ea632309e 100644 --- a/infer/src/IR/IntLit.ml +++ b/infer/src/IR/IntLit.ml @@ -13,6 +13,8 @@ module F = Format (** signed and unsigned integer literals *) type t = bool * Int64.t * bool +exception OversizedShift + (* the first bool indicates whether this is an unsigned value, and the second whether it is a pointer *) @@ -108,7 +110,7 @@ let shift_left (unsigned1, i1, ptr1) (_, i2, _) = | None -> failwithf "Shifting failed with operand %a" Int64.pp i2 | Some i2 - -> if i2 < 0 || i2 >= 64 then failwithf "Oversized shift: %d" i2 ; + -> if i2 < 0 || i2 >= 64 then raise OversizedShift ; let res = Int64.shift_left i1 i2 in (unsigned1, res, ptr1) @@ -117,7 +119,7 @@ let shift_right (unsigned1, i1, ptr1) (_, i2, _) = | None -> failwithf "Shifting failed with operand %a" Int64.pp i2 | Some i2 - -> if i2 < 0 || i2 >= 64 then failwithf "Oversized shift: %d" i2 ; + -> if i2 < 0 || i2 >= 64 then raise OversizedShift ; let res = Int64.shift_right i1 i2 in (unsigned1, res, ptr1) diff --git a/infer/src/IR/IntLit.mli b/infer/src/IR/IntLit.mli index f310edad1..b00d431ee 100644 --- a/infer/src/IR/IntLit.mli +++ b/infer/src/IR/IntLit.mli @@ -14,6 +14,8 @@ module F = Format (** signed and unsigned integer literals *) type t +exception OversizedShift + val add : t -> t -> t val compare : t -> t -> int diff --git a/infer/src/backend/prop.ml b/infer/src/backend/prop.ml index 7d34a6417..fa5f324a1 100644 --- a/infer/src/backend/prop.ml +++ b/infer/src/backend/prop.ml @@ -996,8 +996,9 @@ module Normalize = struct if abs then Exp.get_undefined false else match (e1, e2) with - | Const Cint n, Const Cint m - -> Exp.int (IntLit.shift_left n m) + | Const Cint n, Const Cint m -> ( + try Exp.int (IntLit.shift_left n m) + with IntLit.OversizedShift -> BinOp (Shiftlt, eval e1, eval e2) ) | _, Const Cint m when IntLit.iszero m -> eval e1 | _, Const Cint m when IntLit.isone m @@ -1011,8 +1012,9 @@ module Normalize = struct if abs then Exp.get_undefined false else match (e1, e2) with - | Const Cint n, Const Cint m - -> Exp.int (IntLit.shift_right n m) + | Const Cint n, Const Cint m -> ( + try Exp.int (IntLit.shift_right n m) + with IntLit.OversizedShift -> BinOp (Shiftrt, eval e1, eval e2) ) | _, Const Cint m when IntLit.iszero m -> eval e1 | Const Cint m, _ when IntLit.iszero m