Skip to content

Commit 63acd3f

Browse files
Also prevent overflows in constFold for unop
1 parent d6dd3a8 commit 63acd3f

File tree

1 file changed

+18
-16
lines changed

1 file changed

+18
-16
lines changed

src/cil.ml

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
21842196
let 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) =
26002612
and 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

Comments
 (0)