]> git.lizzy.rs Git - rust.git/commitdiff
fix comparing wide raw pointers
authorRalf Jung <post@ralfj.de>
Wed, 6 Jul 2022 01:11:48 +0000 (21:11 -0400)
committerRalf Jung <post@ralfj.de>
Wed, 6 Jul 2022 01:21:02 +0000 (21:21 -0400)
src/operator.rs
tests/pass/pointers.rs

index 61c72270e9f7e397a3c08ea280f19072860b20e3..33c97e7d31098ed8e67ec2a724864400caa361c2 100644 (file)
@@ -44,9 +44,19 @@ fn binary_ptr_op(
             }
 
             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,
index 898ecc0faf7559124b6a77b68509620f36b3fd23..a0c20af426973a143f6bba381f7f776b20e1870f 100644 (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();
 }