@@ -2181,6 +2181,18 @@ let rec getInteger (e:exp) : cilint option =
21812181 end
21822182 | _ -> None
21832183
2184+ (* * Return the (wrapped) constant i if it fits into ik without any signed overflow,
2185+ otherwise return fallback *)
2186+ let const_if_not_overflow fallback ik i =
2187+ if not (isSigned ik) then
2188+ kintegerCilint ik i
2189+ else
2190+ let i', trunc = truncateCilint ik i in
2191+ if trunc = NoTruncation then
2192+ kintegerCilint ik i
2193+ else
2194+ fallback
2195+
21842196let isZero (e : exp ) : bool =
21852197 match getInteger e with
21862198 | Some n -> is_zero_cilint n
@@ -2518,16 +2530,16 @@ and constFold (machdep: bool) (e: exp) : exp =
25182530 try
25192531 let tk =
25202532 match unrollType tres with
2521- TInt (ik , _ ) -> ik
2533+ | TInt (ik , _ ) -> ik
25222534 | TEnum (ei , _ ) -> ei.ekind
25232535 | _ -> raise Not_found (* probably a float *)
25242536 in
25252537 match constFold machdep e1 with
2526- Const (CInt(i ,ik ,_ )) -> begin
2527- let ic = mkCilintIk ik i in
2538+ | Const (CInt(i ,ik ,s )) -> begin
2539+ let ic = mkCilintIk ik i in
25282540 match unop with
2529- Neg -> kintegerCilint tk (neg_cilint ic)
2530- | BNot -> kintegerCilint tk (lognot_cilint ic)
2541+ Neg -> const_if_not_overflow ( UnOp ( Neg , Const ( CInt (i,ik,s)),tres)) tk (neg_cilint ic)
2542+ | BNot -> const_if_not_overflow ( UnOp ( BNot , Const ( CInt (i,ik,s)),tres)) tk (lognot_cilint ic)
25312543 | LNot -> if is_zero_cilint ic then one else zero
25322544 end
25332545 | e1c -> UnOp (unop, e1c, tres)
@@ -2622,27 +2634,28 @@ and constFoldBinOp (machdep: bool) bop e1 e2 tres =
26222634 with SizeOfError _ -> false
26232635 else false
26242636 in
2637+ let no_ov = const_if_not_overflow (BinOp (bop, e1', e2', tres)) tk in
26252638 (* Assume that the necessary promotions have been done *)
26262639 match bop, getInteger e1', getInteger e2' with
2627- | PlusA , Some i1 , Some i2 -> kintegerCilint tk (add_cilint i1 i2)
2640+ | PlusA , Some i1 , Some i2 -> no_ov (add_cilint i1 i2)
26282641 | PlusA , Some z , _ when is_zero_cilint z -> collapse e2'
26292642 | PlusA , _ , Some z when is_zero_cilint z -> collapse e1'
2630- | MinusA , Some i1 , Some i2 -> kintegerCilint tk (sub_cilint i1 i2)
2643+ | MinusA , Some i1 , Some i2 -> no_ov (sub_cilint i1 i2)
26312644 | MinusA , _ , Some z when is_zero_cilint z -> collapse e1'
2632- | Mult , Some i1 , Some i2 -> kintegerCilint tk (mul_cilint i1 i2)
2645+ | Mult , Some i1 , Some i2 -> no_ov (mul_cilint i1 i2)
26332646 | Mult , Some z , _ when is_zero_cilint z -> collapse0 ()
26342647 | Mult , _ , Some z when is_zero_cilint z -> collapse0 ()
26352648 | Mult , Some o , _ when compare_cilint o one_cilint = 0 -> collapse e2'
26362649 | Mult , _ , Some o when compare_cilint o one_cilint = 0 -> collapse e1'
26372650 | Div , Some i1 , Some i2 -> begin
2638- try kintegerCilint tk (div0_cilint i1 i2)
2651+ try no_ov (div0_cilint i1 i2)
26392652 with Division_by_zero -> BinOp (bop, e1', e2', tres)
2640- end
2653+ end
26412654 | Div , _ , Some o when compare_cilint o one_cilint = 0 -> collapse e1'
26422655 | Mod , Some i1 , Some i2 -> begin
2643- try kintegerCilint tk (rem_cilint i1 i2)
2656+ try no_ov (rem_cilint i1 i2)
26442657 with Division_by_zero -> BinOp (bop, e1', e2', tres)
2645- end
2658+ end
26462659 | Mod , _ , Some o when compare_cilint o one_cilint = 0 -> collapse0 ()
26472660
26482661 | BAnd , Some i1 , Some i2 -> kintegerCilint tk (logand_cilint i1 i2)
0 commit comments