Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 17 additions & 17 deletions src/librustc_mir/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -518,18 +518,19 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
}
}

fn check_unary_op(&mut self, arg: &Operand<'tcx>, source_info: SourceInfo) -> Option<()> {
fn check_unary_op(
&mut self,
op: UnOp,
arg: &Operand<'tcx>,
source_info: SourceInfo,
) -> Option<()> {
self.use_ecx(source_info, |this| {
let ty = arg.ty(&this.local_decls, this.tcx);

if ty.is_integral() {
let arg = this.ecx.eval_operand(arg, None)?;
let prim = this.ecx.read_immediate(arg)?;
// Need to do overflow check here: For actual CTFE, MIR
// generation emits code that does this before calling the op.
if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
throw_panic!(OverflowNeg)
}
let val = this.ecx.read_immediate(this.ecx.eval_operand(arg, None)?)?;
let (_res, overflow, _ty) = this.ecx.overflowing_unary_op(op, val)?;

if overflow {
assert_eq!(op, UnOp::Neg, "Neg is the only UnOp that can overflow");
throw_panic!(OverflowNeg);
}

Ok(())
Expand Down Expand Up @@ -574,11 +575,10 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
if !overflow_check {
self.use_ecx(source_info, |this| {
let l = this.ecx.read_immediate(this.ecx.eval_operand(left, None)?)?;
let (_, overflow, _ty) = this.ecx.overflowing_binary_op(op, l, r)?;
let (_res, overflow, _ty) = this.ecx.overflowing_binary_op(op, l, r)?;

if overflow {
let err = err_panic!(Overflow(op)).into();
return Err(err);
throw_panic!(Overflow(op));
}

Ok(())
Expand Down Expand Up @@ -618,9 +618,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
// Additional checking: if overflow checks are disabled (which is usually the case in
// release mode), then we need to do additional checking here to give lints to the user
// if an overflow would occur.
Rvalue::UnaryOp(UnOp::Neg, arg) if !overflow_check => {
trace!("checking UnaryOp(op = Neg, arg = {:?})", arg);
self.check_unary_op(arg, source_info)?;
Rvalue::UnaryOp(op, arg) if !overflow_check => {
trace!("checking UnaryOp(op = {:?}, arg = {:?})", op, arg);
self.check_unary_op(*op, arg, source_info)?;
}

// Additional checking: check for overflows on integer binary operations and report
Expand Down