diff --git a/src/operator.rs b/src/operator.rs index 61c72270e9f7..33c97e7d3109 100644 --- a/src/operator.rs +++ b/src/operator.rs @@ -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, diff --git a/tests/pass/pointers.rs b/tests/pass/pointers.rs index 898ecc0faf75..a0c20af42697 100644 --- a/tests/pass/pointers.rs +++ b/tests/pass/pointers.rs @@ -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(); }