Skip to content

Commit 7dff647

Browse files
committed
Ensure miri can do bit ops on pointer values
1 parent 7602267 commit 7dff647

File tree

3 files changed

+16
-12
lines changed

3 files changed

+16
-12
lines changed

src/librustc_mir/interpret/intrinsics.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
9595
| "bitreverse" => {
9696
let ty = substs.type_at(0);
9797
let layout_of = self.layout_of(ty)?;
98-
let bits = self.read_scalar(args[0])?.to_bits(layout_of.size)?;
98+
let val = self.read_scalar(args[0])?.not_undef()?;
99+
let bits = self.force_bits(val, layout_of.size)?;
99100
let kind = match layout_of.abi {
100101
ty::layout::Abi::Scalar(ref scalar) => scalar.value,
101102
_ => throw_unsup!(TypeNotPrimitive(ty)),
@@ -149,7 +150,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
149150
// term since the sign of the second term can be inferred from this and
150151
// the fact that the operation has overflowed (if either is 0 no
151152
// overflow can occur)
152-
let first_term: u128 = l.to_scalar()?.to_bits(l.layout.size)?;
153+
let first_term: u128 = self.force_bits(l.to_scalar()?, l.layout.size)?;
153154
let first_term_positive = first_term & (1 << (num_bits-1)) == 0;
154155
if first_term_positive {
155156
// Negative overflow not possible since the positive first term
@@ -187,7 +188,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
187188
let (val, overflowed, _ty) = self.overflowing_binary_op(bin_op, l, r)?;
188189
if overflowed {
189190
let layout = self.layout_of(substs.type_at(0))?;
190-
let r_val = r.to_scalar()?.to_bits(layout.size)?;
191+
let r_val = self.force_bits(r.to_scalar()?, layout.size)?;
191192
throw_ub_format!("Overflowing shift by {} in `{}`", r_val, intrinsic_name);
192193
}
193194
self.write_scalar(val, dest)?;
@@ -196,8 +197,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
196197
// rotate_left: (X << (S % BW)) | (X >> ((BW - S) % BW))
197198
// rotate_right: (X << ((BW - S) % BW)) | (X >> (S % BW))
198199
let layout = self.layout_of(substs.type_at(0))?;
199-
let val_bits = self.read_scalar(args[0])?.to_bits(layout.size)?;
200-
let raw_shift_bits = self.read_scalar(args[1])?.to_bits(layout.size)?;
200+
let val = self.read_scalar(args[0])?.not_undef()?;
201+
let val_bits = self.force_bits(val, layout.size)?;
202+
let raw_shift = self.read_scalar(args[1])?.not_undef()?;
203+
let raw_shift_bits = self.force_bits(raw_shift, layout.size)?;
201204
let width_bits = layout.size.bits() as u128;
202205
let shift_bits = raw_shift_bits % width_bits;
203206
let inv_shift_bits = (width_bits - shift_bits) % width_bits;

src/librustc_mir/interpret/operand.rs

+4-5
Original file line numberDiff line numberDiff line change
@@ -629,11 +629,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
629629
// post-process
630630
Ok(match *discr_kind {
631631
layout::DiscriminantKind::Tag => {
632-
let bits_discr = match raw_discr.to_bits(discr_val.layout.size) {
633-
Ok(raw_discr) => raw_discr,
634-
Err(_) =>
635-
throw_unsup!(InvalidDiscriminant(raw_discr.erase_tag())),
636-
};
632+
let bits_discr = raw_discr
633+
.not_undef()
634+
.and_then(|raw_discr| self.force_bits(raw_discr, discr_val.layout.size))
635+
.map_err(|_| err_unsup!(InvalidDiscriminant(raw_discr.erase_tag())))?;
637636
let real_discr = if discr_val.layout.ty.is_signed() {
638637
// going from layout tag type to typeck discriminant type
639638
// requires first sign extending with the layout discriminant

src/librustc_mir/interpret/traits.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
144144
let size = alloc.read_ptr_sized(
145145
self,
146146
vtable.offset(pointer_size, self)?
147-
)?.to_bits(pointer_size)? as u64;
147+
)?.not_undef()?;
148+
let size = self.force_bits(size, pointer_size)? as u64;
148149
let align = alloc.read_ptr_sized(
149150
self,
150151
vtable.offset(pointer_size * 2, self)?,
151-
)?.to_bits(pointer_size)? as u64;
152+
)?.not_undef()?;
153+
let align = self.force_bits(align, pointer_size)? as u64;
152154
Ok((Size::from_bytes(size), Align::from_bytes(align).unwrap()))
153155
}
154156
}

0 commit comments

Comments
 (0)