[const-prop] Replace most UnaryOp handling with use of InterpCx

This commit is contained in:
Wesley Wiser 2019-09-06 07:48:52 -04:00
parent 1c219bb34b
commit 644d4f3ee9

View File

@ -325,39 +325,28 @@ fn const_prop(
},
Rvalue::UnaryOp(op, ref arg) => {
let def_id = if self.tcx.is_closure(self.source.def_id()) {
self.tcx.closure_base_def_id(self.source.def_id())
} else {
self.source.def_id()
};
let generics = self.tcx.generics_of(def_id);
if generics.requires_monomorphization(self.tcx) {
// FIXME: can't handle code with generics
return None;
}
let overflow_check = self.tcx.sess.overflow_checks();
let arg = self.eval_operand(arg, source_info)?;
let oflo_check = self.tcx.sess.overflow_checks();
let val = self.use_ecx(source_info, |this| {
let prim = this.ecx.read_immediate(arg)?;
match op {
UnOp::Neg => {
// We check overflow in debug mode already
// so should only check in release mode.
if !oflo_check
&& prim.layout.ty.is_signed()
&& prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
self.use_ecx(source_info, |this| {
// We check overflow in debug mode already
// so should only check in release mode.
if op == UnOp::Neg && !overflow_check {
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)
}
}
UnOp::Not => {
// Cannot overflow
}
}
// Now run the actual operation.
this.ecx.unary_op(op, prim)
})?;
Some(val.into())
this.ecx.eval_rvalue_into_place(rvalue, place)?;
this.ecx.eval_place_to_op(place, Some(place_layout))
})
}
Rvalue::CheckedBinaryOp(op, ref left, ref right) |
Rvalue::BinaryOp(op, ref left, ref right) => {