const-prop: use overflowing_unary_op for overflowing checking of unary ops
This commit is contained in:
parent
7d2f6ae001
commit
ae23f7020a
@ -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);
|
||||
let val = this.ecx.read_immediate(this.ecx.eval_operand(arg, None)?)?;
|
||||
let (_res, overflow, _ty) = this.ecx.overflowing_unary_op(op, val)?;
|
||||
|
||||
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)
|
||||
}
|
||||
if overflow {
|
||||
assert_eq!(op, UnOp::Neg, "Neg is the only UnOp that can overflow");
|
||||
throw_panic!(OverflowNeg);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -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(())
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user