adjust for ptr_op now being called type-based
This commit is contained in:
parent
247786dba6
commit
bb6a91dc94
2 changed files with 24 additions and 28 deletions
|
|
@ -179,13 +179,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn ptr_op(
|
||||
fn binary_ptr_op(
|
||||
ecx: &rustc_mir::interpret::InterpCx<'mir, 'tcx, Self>,
|
||||
bin_op: mir::BinOp,
|
||||
left: ImmTy<'tcx, Tag>,
|
||||
right: ImmTy<'tcx, Tag>,
|
||||
) -> InterpResult<'tcx, (Scalar<Tag>, bool)> {
|
||||
ecx.ptr_op(bin_op, left, right)
|
||||
ecx.binary_ptr_op(bin_op, left, right)
|
||||
}
|
||||
|
||||
fn box_alloc(
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub trait EvalContextExt<'tcx> {
|
|||
ptr: Pointer<Tag>
|
||||
) -> InterpResult<'tcx>;
|
||||
|
||||
fn ptr_op(
|
||||
fn binary_ptr_op(
|
||||
&self,
|
||||
bin_op: mir::BinOp,
|
||||
left: ImmTy<'tcx, Tag>,
|
||||
|
|
@ -46,7 +46,7 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
|
|||
ptr.check_in_alloc(size, CheckInAllocMsg::InboundsTest)
|
||||
}
|
||||
|
||||
fn ptr_op(
|
||||
fn binary_ptr_op(
|
||||
&self,
|
||||
bin_op: mir::BinOp,
|
||||
left: ImmTy<'tcx, Tag>,
|
||||
|
|
@ -56,21 +56,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
|
|||
|
||||
trace!("ptr_op: {:?} {:?} {:?}", *left, bin_op, *right);
|
||||
|
||||
// Treat everything of integer *type* at integer *value*.
|
||||
if left.layout.ty.is_integral() {
|
||||
// This is actually an integer operation, so dispatch back to the core engine.
|
||||
// TODO: Once intptrcast is the default, librustc_mir should never even call us
|
||||
// for integer types.
|
||||
assert!(right.layout.ty.is_integral());
|
||||
let l_bits = self.force_bits(left.imm.to_scalar()?, left.layout.size)?;
|
||||
let r_bits = self.force_bits(right.imm.to_scalar()?, right.layout.size)?;
|
||||
|
||||
let left = ImmTy::from_scalar(Scalar::from_uint(l_bits, left.layout.size), left.layout);
|
||||
let right = ImmTy::from_scalar(Scalar::from_uint(r_bits, left.layout.size), right.layout);
|
||||
|
||||
return self.binary_op(bin_op, left, right);
|
||||
}
|
||||
|
||||
// Operations that support fat pointers
|
||||
match bin_op {
|
||||
Eq | Ne => {
|
||||
|
|
@ -92,7 +77,6 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
|
|||
let left = left.to_scalar()?;
|
||||
let right_layout = right.layout;
|
||||
let right = right.to_scalar()?;
|
||||
debug_assert!(left.is_ptr() || right.is_ptr() || bin_op == Offset);
|
||||
|
||||
Ok(match bin_op {
|
||||
Offset => {
|
||||
|
|
@ -109,8 +93,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
|
|||
}
|
||||
// These need both to be pointer, and fail if they are not in the same location
|
||||
Lt | Le | Gt | Ge | Sub if left.is_ptr() && right.is_ptr() => {
|
||||
let left = left.to_ptr().expect("we checked is_ptr");
|
||||
let right = right.to_ptr().expect("we checked is_ptr");
|
||||
let left = left.assert_ptr();
|
||||
let right = right.assert_ptr();
|
||||
if left.alloc_id == right.alloc_id {
|
||||
let res = match bin_op {
|
||||
Lt => left.offset < right.offset,
|
||||
|
|
@ -136,10 +120,22 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
|
|||
throw_unsup!(InvalidPointerMath)
|
||||
}
|
||||
}
|
||||
Lt | Le | Gt | Ge if left.is_bits() && right.is_bits() => {
|
||||
let left = left.assert_bits(self.memory().pointer_size());
|
||||
let right = right.assert_bits(self.memory().pointer_size());
|
||||
let res = match bin_op {
|
||||
Lt => left < right,
|
||||
Le => left <= right,
|
||||
Gt => left > right,
|
||||
Ge => left >= right,
|
||||
_ => bug!("We already established it has to be one of these operators."),
|
||||
};
|
||||
Ok((Scalar::from_bool(res), false))
|
||||
}
|
||||
Gt | Ge if left.is_ptr() && right.is_bits() => {
|
||||
// "ptr >[=] integer" can be tested if the integer is small enough.
|
||||
let left = left.to_ptr().expect("we checked is_ptr");
|
||||
let right = right.to_bits(self.memory().pointer_size()).expect("we checked is_bits");
|
||||
let left = left.assert_ptr();
|
||||
let right = right.assert_bits(self.memory().pointer_size());
|
||||
let (_alloc_size, alloc_align) = self.memory()
|
||||
.get_size_and_align(left.alloc_id, AllocCheck::MaybeDead)
|
||||
.expect("alloc info with MaybeDead cannot fail");
|
||||
|
|
@ -162,8 +158,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
|
|||
// Cast to i128 is fine as we checked the kind to be ptr-sized
|
||||
self.ptr_int_arithmetic(
|
||||
bin_op,
|
||||
left.to_ptr().expect("we checked is_ptr"),
|
||||
right.to_bits(self.memory().pointer_size()).expect("we checked is_bits"),
|
||||
left.assert_ptr(),
|
||||
right.assert_bits(self.memory().pointer_size()),
|
||||
right_layout.abi.is_signed(),
|
||||
)?
|
||||
}
|
||||
|
|
@ -172,8 +168,8 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
|
|||
// This is a commutative operation, just swap the operands
|
||||
self.ptr_int_arithmetic(
|
||||
bin_op,
|
||||
right.to_ptr().expect("we checked is_ptr"),
|
||||
left.to_bits(self.memory().pointer_size()).expect("we checked is_bits"),
|
||||
right.assert_ptr(),
|
||||
left.assert_bits(self.memory().pointer_size()),
|
||||
left_layout.abi.is_signed(),
|
||||
)?
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue