Skip to content

Commit ae23f70

Browse files
committed
const-prop: use overflowing_unary_op for overflowing checking of unary ops
1 parent 7d2f6ae commit ae23f70

File tree

1 file changed

+17
-17
lines changed

1 file changed

+17
-17
lines changed

src/librustc_mir/transform/const_prop.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)