fix comparing wide raw pointers

This commit is contained in:
Ralf Jung 2022-07-05 21:11:48 -04:00
parent 1118d94bdf
commit 6c8ad4abc9
2 changed files with 38 additions and 3 deletions

View file

@ -44,9 +44,19 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
}
Lt | Le | Gt | Ge => {
// Just compare the integers.
let left = left.to_scalar()?.to_bits(left.layout.size)?;
let right = right.to_scalar()?.to_bits(right.layout.size)?;
let size = self.pointer_size();
// Just compare the bits. ScalarPairs are compared lexicographically.
// We thus always compare pairs and simply fill scalars up with 0.
let left = match **left {
Immediate::Scalar(l) => (l.check_init()?.to_bits(size)?, 0),
Immediate::ScalarPair(l1, l2) =>
(l1.check_init()?.to_bits(size)?, l2.check_init()?.to_bits(size)?),
};
let right = match **right {
Immediate::Scalar(r) => (r.check_init()?.to_bits(size)?, 0),
Immediate::ScalarPair(r1, r2) =>
(r1.check_init()?.to_bits(size)?, r2.check_init()?.to_bits(size)?),
};
let res = match bin_op {
Lt => left < right,
Le => left <= right,

View file

@ -1,3 +1,5 @@
use std::mem::transmute;
fn one_line_ref() -> i16 {
*&1
}
@ -48,6 +50,27 @@ fn dangling_pointer() -> *const i32 {
&b.0 as *const i32
}
fn wide_ptr_ops() {
let a: *const dyn Send = &1 as &dyn Send;
let b: *const dyn Send = &1 as &dyn Send;
let _val = a == b;
let _val = a != b;
let _val = a < b;
let _val = a <= b;
let _val = a > b;
let _val = a >= b;
let a: *const [u8] = unsafe { transmute((1usize, 1usize)) };
let b: *const [u8] = unsafe { transmute((1usize, 2usize)) };
// confirmed with rustc.
assert!(!(a == b));
assert!(a != b);
assert!(a <= b);
assert!(a < b);
assert!(!(a >= b));
assert!(!(a > b));
}
fn main() {
assert_eq!(one_line_ref(), 1);
assert_eq!(basic_ref(), 1);
@ -91,4 +114,6 @@ fn main() {
assert!(dangling > 2);
assert!(dangling > 3);
assert!(dangling >= 4);
wide_ptr_ops();
}