summaryrefslogtreecommitdiffstats
path: root/src/test/ui/consts/ptr_comparisons.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/consts/ptr_comparisons.rs
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/consts/ptr_comparisons.rs')
-rw-r--r--src/test/ui/consts/ptr_comparisons.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/test/ui/consts/ptr_comparisons.rs b/src/test/ui/consts/ptr_comparisons.rs
new file mode 100644
index 000000000..20233db09
--- /dev/null
+++ b/src/test/ui/consts/ptr_comparisons.rs
@@ -0,0 +1,73 @@
+// compile-flags: --crate-type=lib
+// normalize-stderr-32bit: "8 bytes" -> "$$TWO_WORDS bytes"
+// normalize-stderr-64bit: "16 bytes" -> "$$TWO_WORDS bytes"
+// normalize-stderr-32bit: "size 4" -> "size $$WORD"
+// normalize-stderr-64bit: "size 8" -> "size $$WORD"
+
+#![feature(
+ core_intrinsics,
+ const_raw_ptr_comparison,
+)]
+
+const FOO: &usize = &42;
+
+macro_rules! check {
+ (eq, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));
+ };
+ (ne, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));
+ };
+ (!eq, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8));
+ };
+ (!ne, $a:expr, $b:expr) => {
+ pub const _: () =
+ assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8));
+ };
+}
+
+check!(eq, 0, 0);
+check!(ne, 0, 1);
+check!(!eq, 0, 1);
+check!(!ne, 0, 0);
+check!(ne, FOO as *const _, 0);
+check!(!eq, FOO as *const _, 0);
+// We want pointers to be equal to themselves, but aren't checking this yet because
+// there are some open questions (e.g. whether function pointers to the same function
+// compare equal, they don't necessarily at runtime).
+// The case tested here should work eventually, but does not work yet.
+check!(!eq, FOO as *const _, FOO as *const _);
+check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0);
+check!(!eq, unsafe { (FOO as *const usize).offset(1) }, 0);
+
+check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
+check!(!eq, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
+
+///////////////////////////////////////////////////////////////////////////////
+// If any of the below start compiling, make sure to add a `check` test for it.
+// These invocations exist as canaries so we don't forget to check that the
+// behaviour of `guaranteed_eq` and `guaranteed_ne` is still correct.
+// All of these try to obtain an out of bounds pointer in some manner. If we
+// can create out of bounds pointers, we can offset a pointer far enough that
+// at runtime it would be zero and at compile-time it would not be zero.
+
+const _: *const usize = unsafe { (FOO as *const usize).offset(2) };
+
+const _: *const u8 =
+ unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
+//~^ ERROR evaluation of constant value failed
+//~| out-of-bounds
+
+const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
+//~^ ERROR any use of this value will cause an error
+//~| unable to turn pointer into raw bytes
+//~| WARN this was previously accepted by the compiler but is being phased out
+
+const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
+//~^ ERROR any use of this value will cause an error
+//~| unable to turn pointer into raw bytes
+//~| WARN this was previously accepted by the compiler but is being phased out