@@ -1654,11 +1654,26 @@ fn trans_unary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1654
1654
ast:: UnNeg => {
1655
1655
let datum = unpack_datum ! ( bcx, trans( bcx, sub_expr) ) ;
1656
1656
let val = datum. to_llscalarish ( bcx) ;
1657
- let llneg = {
1657
+ let ( bcx , llneg) = {
1658
1658
if ty:: type_is_fp ( un_ty) {
1659
- FNeg ( bcx, val, debug_loc)
1659
+ let result = FNeg ( bcx, val, debug_loc) ;
1660
+ ( bcx, result)
1660
1661
} 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)
1662
1677
}
1663
1678
} ;
1664
1679
immediate_rvalue_bcx ( bcx, llneg, un_ty) . to_expr_datumblock ( )
0 commit comments