@@ -518,18 +518,19 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
518518 }
519519 }
520520
521- fn check_unary_op ( & mut self , arg : & Operand < ' tcx > , source_info : SourceInfo ) -> Option < ( ) > {
521+ fn check_unary_op (
522+ & mut self ,
523+ op : UnOp ,
524+ arg : & Operand < ' tcx > ,
525+ source_info : SourceInfo ,
526+ ) -> Option < ( ) > {
522527 self . use_ecx ( source_info, |this| {
523- let ty = arg. ty ( & this. local_decls , this. tcx ) ;
524-
525- if ty. is_integral ( ) {
526- let arg = this. ecx . eval_operand ( arg, None ) ?;
527- let prim = this. ecx . read_immediate ( arg) ?;
528- // Need to do overflow check here: For actual CTFE, MIR
529- // generation emits code that does this before calling the op.
530- if prim. to_bits ( ) ? == ( 1 << ( prim. layout . size . bits ( ) - 1 ) ) {
531- throw_panic ! ( OverflowNeg )
532- }
528+ let val = this. ecx . read_immediate ( this. ecx . eval_operand ( arg, None ) ?) ?;
529+ let ( _res, overflow, _ty) = this. ecx . overflowing_unary_op ( op, val) ?;
530+
531+ if overflow {
532+ assert_eq ! ( op, UnOp :: Neg , "Neg is the only UnOp that can overflow" ) ;
533+ throw_panic ! ( OverflowNeg ) ;
533534 }
534535
535536 Ok ( ( ) )
@@ -574,11 +575,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
574575 if !overflow_check {
575576 self . use_ecx ( source_info, |this| {
576577 let l = this. ecx . read_immediate ( this. ecx . eval_operand ( left, None ) ?) ?;
577- let ( _ , overflow, _ty) = this. ecx . overflowing_binary_op ( op, l, r) ?;
578+ let ( _res , overflow, _ty) = this. ecx . overflowing_binary_op ( op, l, r) ?;
578579
579580 if overflow {
580- let err = err_panic ! ( Overflow ( op) ) . into ( ) ;
581- return Err ( err) ;
581+ throw_panic ! ( Overflow ( op) ) ;
582582 }
583583
584584 Ok ( ( ) )
@@ -618,9 +618,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
618618 // Additional checking: if overflow checks are disabled (which is usually the case in
619619 // release mode), then we need to do additional checking here to give lints to the user
620620 // if an overflow would occur.
621- Rvalue :: UnaryOp ( UnOp :: Neg , arg) if !overflow_check => {
622- trace ! ( "checking UnaryOp(op = Neg , arg = {:?})" , arg) ;
623- self . check_unary_op ( arg, source_info) ?;
621+ Rvalue :: UnaryOp ( op , arg) if !overflow_check => {
622+ trace ! ( "checking UnaryOp(op = {:?} , arg = {:?})" , op , arg) ;
623+ self . check_unary_op ( * op , arg, source_info) ?;
624624 }
625625
626626 // Additional checking: check for overflows on integer binary operations and report
0 commit comments