From 7728de3e608ee0b020bd024b9ea0ae386bad3f40 Mon Sep 17 00:00:00 2001 From: Scott Olson Date: Sun, 16 Oct 2016 17:18:06 -0600 Subject: [PATCH] Do not force_allocate checked binop destination. --- src/interpreter/mod.rs | 41 ++++++++++++------------ src/interpreter/terminator/intrinsics.rs | 34 ++++---------------- 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 0380c0b0182..4013d17ede3 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -394,6 +394,17 @@ fn pop_stack_frame(&mut self) -> EvalResult<'tcx, ()> { Ok(()) } + fn binop_with_overflow( + &mut self, + op: mir::BinOp, + left: &mir::Operand<'tcx>, + right: &mir::Operand<'tcx>, + ) -> EvalResult<'tcx, (PrimVal, bool)> { + let left_primval = self.eval_operand_to_primval(left)?; + let right_primval = self.eval_operand_to_primval(right)?; + primval::binary_op(op, left_primval, right_primval) + } + /// Applies the binary operation `op` to the two operands and writes a tuple of the result /// and a boolean signifying the potential overflow to the destination. fn intrinsic_with_overflow( @@ -402,25 +413,15 @@ fn intrinsic_with_overflow( left: &mir::Operand<'tcx>, right: &mir::Operand<'tcx>, dest: Lvalue, - dest_layout: &'tcx Layout, + dest_ty: Ty<'tcx>, ) -> EvalResult<'tcx, ()> { - use rustc::ty::layout::Layout::*; - let tup_layout = match *dest_layout { - Univariant { ref variant, .. } => variant, - _ => bug!("checked bin op returns something other than a tuple"), - }; - - let overflowed = self.intrinsic_overflowing(op, left, right, dest)?; - - // FIXME(solson) - let dest = self.force_allocation(dest)?.to_ptr(); - - let offset = tup_layout.offsets[1].bytes() as isize; - self.memory.write_bool(dest.offset(offset), overflowed) + let (val, overflowed) = self.binop_with_overflow(op, left, right)?; + let val = Value::ByValPair(val, PrimVal::Bool(overflowed)); + self.write_value(val, dest, dest_ty) } - /// Applies the binary operation `op` to the arguments and writes the result to the destination. - /// Returns `true` if the operation overflowed. + /// Applies the binary operation `op` to the arguments and writes the result to the + /// destination. Returns `true` if the operation overflowed. fn intrinsic_overflowing( &mut self, op: mir::BinOp, @@ -428,11 +429,9 @@ fn intrinsic_overflowing( right: &mir::Operand<'tcx>, dest: Lvalue, ) -> EvalResult<'tcx, bool> { - let left_primval = self.eval_operand_to_primval(left)?; - let right_primval = self.eval_operand_to_primval(right)?; - let (val, overflow) = primval::binary_op(op, left_primval, right_primval)?; + let (val, overflowed) = self.binop_with_overflow(op, left, right)?; self.write_primval(dest, val)?; - Ok(overflow) + Ok(overflowed) } fn assign_fields>( @@ -479,7 +478,7 @@ fn eval_rvalue_into_lvalue( } CheckedBinaryOp(bin_op, ref left, ref right) => { - self.intrinsic_with_overflow(bin_op, left, right, dest, dest_layout)?; + self.intrinsic_with_overflow(bin_op, left, right, dest, dest_ty)?; } UnaryOp(un_op, ref operand) => { diff --git a/src/interpreter/terminator/intrinsics.rs b/src/interpreter/terminator/intrinsics.rs index 49cef471dab..85559a7efc7 100644 --- a/src/interpreter/terminator/intrinsics.rs +++ b/src/interpreter/terminator/intrinsics.rs @@ -31,35 +31,15 @@ pub(super) fn call_intrinsic( let intrinsic_name = &self.tcx.item_name(def_id).as_str()[..]; match intrinsic_name { - "add_with_overflow" => { - self.intrinsic_with_overflow( - mir::BinOp::Add, - &args[0], - &args[1], - dest, - dest_layout, - )? - } + "add_with_overflow" => + self.intrinsic_with_overflow(mir::BinOp::Add, &args[0], &args[1], dest, dest_ty)?, - "sub_with_overflow" => { - self.intrinsic_with_overflow( - mir::BinOp::Sub, - &args[0], - &args[1], - dest, - dest_layout, - )? - } + "sub_with_overflow" => + self.intrinsic_with_overflow(mir::BinOp::Sub, &args[0], &args[1], dest, dest_ty)?, + + "mul_with_overflow" => + self.intrinsic_with_overflow(mir::BinOp::Mul, &args[0], &args[1], dest, dest_ty)?, - "mul_with_overflow" => { - self.intrinsic_with_overflow( - mir::BinOp::Mul, - &args[0], - &args[1], - dest, - dest_layout, - )? - } "arith_offset" => { let ptr = args_ptrs[0].read_ptr(&self.memory)?; -- GitLab