Skip to content

Commit d9e0a57

Browse files
committed
Add conditional overflow-checking to signed negate operator.
1 parent c864d90 commit d9e0a57

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

src/librustc_trans/trans/expr.rs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1654,11 +1654,26 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
16541654
ast::UnNeg => {
16551655
let datum = unpack_datum!(bcx, trans(bcx, sub_expr));
16561656
let val = datum.to_llscalarish(bcx);
1657-
let llneg = {
1657+
let (bcx, llneg) = {
16581658
if ty::type_is_fp(un_ty) {
1659-
FNeg(bcx, val, debug_loc)
1659+
let result = FNeg(bcx, val, debug_loc);
1660+
(bcx, result)
16601661
} else {
1661-
Neg(bcx, val, debug_loc)
1662+
let is_signed = ty::type_is_signed(un_ty);
1663+
let result = Neg(bcx, val, debug_loc);
1664+
let bcx = if bcx.ccx().check_overflow() && is_signed {
1665+
let (llty, min) = base::llty_and_min_for_signed_ty(bcx, un_ty);
1666+
let is_min = ICmp(bcx, llvm::IntEQ, val,
1667+
C_integral(llty, min, true), debug_loc);
1668+
with_cond(bcx, is_min, |bcx| {
1669+
let msg = InternedString::new(
1670+
"attempted to negate with overflow");
1671+
controlflow::trans_fail(bcx, expr_info(expr), msg)
1672+
})
1673+
} else {
1674+
bcx
1675+
};
1676+
(bcx, result)
16621677
}
16631678
};
16641679
immediate_rvalue_bcx(bcx, llneg, un_ty).to_expr_datumblock()

0 commit comments

Comments
 (0)