@@ -1530,11 +1530,26 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1530
1530
ast:: UnNeg => {
1531
1531
let datum = unpack_datum ! ( bcx, trans( bcx, sub_expr) ) ;
1532
1532
let val = datum. to_llscalarish ( bcx) ;
1533
- let llneg = {
1533
+ let ( bcx , llneg) = {
1534
1534
if ty:: type_is_fp ( un_ty) {
1535
- FNeg ( bcx, val, debug_loc)
1535
+ let result = FNeg ( bcx, val, debug_loc) ;
1536
+ ( bcx, result)
1536
1537
} else {
1537
- Neg ( bcx, val, debug_loc)
1538
+ let is_signed = ty:: type_is_signed ( un_ty) ;
1539
+ let result = Neg ( bcx, val, debug_loc) ;
1540
+ let bcx = if bcx. ccx ( ) . check_overflow ( ) && is_signed {
1541
+ let ( llty, min) = base:: llty_and_min_for_signed_ty ( bcx, un_ty) ;
1542
+ let is_min = ICmp ( bcx, llvm:: IntEQ , val,
1543
+ C_integral ( llty, min, true ) , debug_loc) ;
1544
+ with_cond ( bcx, is_min, |bcx| {
1545
+ let msg = InternedString :: new (
1546
+ "attempted to negate with overflow" ) ;
1547
+ controlflow:: trans_fail ( bcx, expr_info ( expr) , msg)
1548
+ } )
1549
+ } else {
1550
+ bcx
1551
+ } ;
1552
+ ( bcx, result)
1538
1553
}
1539
1554
} ;
1540
1555
immediate_rvalue_bcx ( bcx, llneg, un_ty) . to_expr_datumblock ( )
0 commit comments