adjust for typed binary/unary_op

This commit is contained in:
Ralf Jung 2019-08-10 21:19:25 +02:00
parent bfd6181d34
commit 4f1c9bb607
3 changed files with 14 additions and 14 deletions

View File

@ -10,7 +10,7 @@ use rand::rngs::StdRng;
use syntax::attr;
use syntax::symbol::sym;
use rustc::hir::def_id::DefId;
use rustc::ty::{self, layout::{Size, LayoutOf}, TyCtxt};
use rustc::ty::{self, Ty, TyCtxt, layout::{Size, LayoutOf}};
use rustc::mir;
use crate::*;
@ -191,7 +191,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
bin_op: mir::BinOp,
left: ImmTy<'tcx, Tag>,
right: ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, (Scalar<Tag>, bool)> {
) -> InterpResult<'tcx, (Scalar<Tag>, bool, Ty<'tcx>)> {
ecx.binary_ptr_op(bin_op, left, right)
}

View File

@ -14,7 +14,7 @@ pub trait EvalContextExt<'tcx> {
bin_op: mir::BinOp,
left: ImmTy<'tcx, Tag>,
right: ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, (Scalar<Tag>, bool)>;
) -> InterpResult<'tcx, (Scalar<Tag>, bool, Ty<'tcx>)>;
fn ptr_eq(
&self,
@ -43,7 +43,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
bin_op: mir::BinOp,
left: ImmTy<'tcx, Tag>,
right: ImmTy<'tcx, Tag>,
) -> InterpResult<'tcx, (Scalar<Tag>, bool)> {
) -> InterpResult<'tcx, (Scalar<Tag>, bool, Ty<'tcx>)> {
use rustc::mir::BinOp::*;
trace!("ptr_op: {:?} {:?} {:?}", *left, bin_op, *right);
@ -59,7 +59,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
self.ptr_eq(left2.not_undef()?, right2.not_undef()?)?,
_ => bug!("Type system should not allow comparing Scalar with ScalarPair"),
};
(Scalar::from_bool(if bin_op == Eq { eq } else { !eq }), false)
(Scalar::from_bool(if bin_op == Eq { eq } else { !eq }), false, self.tcx.types.bool)
}
Lt | Le | Gt | Ge => {
@ -74,7 +74,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
Ge => left >= right,
_ => bug!("We already established it has to be one of these operators."),
};
(Scalar::from_bool(res), false)
(Scalar::from_bool(res), false, self.tcx.types.bool)
}
Offset => {
@ -87,7 +87,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
pointee_ty,
right.to_scalar()?.to_isize(self)?,
)?;
(ptr, false)
(ptr, false, left.layout.ty)
}
_ => bug!("Invalid operator on pointers: {:?}", bin_op)

View File

@ -5,7 +5,7 @@ use rustc::ty::layout::{self, LayoutOf, Size, Align};
use rustc::ty;
use crate::{
PlaceTy, OpTy, ImmTy, Immediate, Scalar, Tag,
PlaceTy, OpTy, Immediate, Scalar, Tag,
OperatorEvalContextExt
};
@ -120,7 +120,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
this.memory().check_ptr_access(place.ptr, place.layout.size, align)?;
// binary_op will bail if either of them is not a scalar
let (eq, _) = this.binary_op(mir::BinOp::Eq, old, expect_old)?;
let eq = this.overflowing_binary_op(mir::BinOp::Eq, old, expect_old)?.0;
let res = Immediate::ScalarPair(old.to_scalar_or_undef(), eq.into());
this.write_immediate(res, dest)?; // old value is returned
// update ptr depending on comparison
@ -183,13 +183,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
_ => bug!(),
};
// Atomics wrap around on overflow.
let (val, _overflowed) = this.binary_op(op, old, rhs)?;
let val = this.binary_op(op, old, rhs)?;
let val = if neg {
this.unary_op(mir::UnOp::Not, ImmTy::from_scalar(val, old.layout))?
this.unary_op(mir::UnOp::Not, val)?
} else {
val
};
this.write_scalar(val, place.into())?;
this.write_immediate(*val, place.into())?;
}
"breakpoint" => unimplemented!(), // halt miri
@ -312,7 +312,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let a = this.read_immediate(args[0])?;
let b = this.read_immediate(args[1])?;
// check x % y != 0
if this.binary_op(mir::BinOp::Rem, a, b)?.0.to_bits(dest.layout.size)? != 0 {
if this.overflowing_binary_op(mir::BinOp::Rem, a, b)?.0.to_bits(dest.layout.size)? != 0 {
// Check if `b` is -1, which is the "min_value / -1" case.
let minus1 = Scalar::from_int(-1, dest.layout.size);
return Err(if b.to_scalar().unwrap() == minus1 {
@ -515,7 +515,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"unchecked_mul" => mir::BinOp::Mul,
_ => bug!(),
};
let (res, overflowed) = this.binary_op(op, l, r)?;
let (res, overflowed, _ty) = this.overflowing_binary_op(op, l, r)?;
if overflowed {
throw_ub_format!("Overflowing arithmetic in {}", intrinsic_name.get());
}