@@ -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)
@@ -2600,16 +2612,6 @@ and constFoldLval machdep (host,offset) =
26002612and constFoldBinOp (machdep : bool ) bop e1 e2 tres =
26012613 let e1' = constFold machdep e1 in
26022614 let e2' = constFold machdep e2 in
2603- let if_not_overflow fallback ik i =
2604- if not (isSigned ik) then
2605- kintegerCilint ik i
2606- else
2607- let i', trunc = truncateCilint ik i in
2608- if trunc = NoTruncation then
2609- kintegerCilint ik i
2610- else
2611- fallback
2612- in
26132615 if isIntegralType tres then begin
26142616 let newe =
26152617 let tk =
@@ -2632,7 +2634,7 @@ and constFoldBinOp (machdep: bool) bop e1 e2 tres =
26322634 with SizeOfError _ -> false
26332635 else false
26342636 in
2635- let no_ov = if_not_overflow (BinOp (bop, e1', e2', tres)) tk in
2637+ let no_ov = const_if_not_overflow (BinOp (bop, e1', e2', tres)) tk in
26362638 (* Assume that the necessary promotions have been done *)
26372639 match bop, getInteger e1', getInteger e2' with
26382640 | PlusA , Some i1 , Some i2 -> no_ov (add_cilint i1 i2)
0 commit comments