rust/tests/ui/consts/ptr_comparisons.rs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

64 lines
2.5 KiB
Rust
Raw Normal View History

2020-07-30 05:27:34 -05:00
// compile-flags: --crate-type=lib
2021-07-12 17:21:35 -05:00
// normalize-stderr-32bit: "8 bytes" -> "$$TWO_WORDS bytes"
// normalize-stderr-64bit: "16 bytes" -> "$$TWO_WORDS bytes"
2020-08-17 08:31:48 -05:00
// normalize-stderr-32bit: "size 4" -> "size $$WORD"
// normalize-stderr-64bit: "size 8" -> "size $$WORD"
2020-07-30 05:27:34 -05:00
#![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_cmp($a as *const u8, $b as *const u8) == 1);
2020-07-30 05:27:34 -05:00
};
(ne, $a:expr, $b:expr) => {
pub const _: () =
assert!(std::intrinsics::ptr_guaranteed_cmp($a as *const u8, $b as *const u8) == 0);
2020-07-30 05:27:34 -05:00
};
(!, $a:expr, $b:expr) => {
2020-07-30 05:27:34 -05:00
pub const _: () =
assert!(std::intrinsics::ptr_guaranteed_cmp($a as *const u8, $b as *const u8) == 2);
2020-07-30 05:27:34 -05:00
};
}
check!(eq, 0, 0);
check!(ne, 0, 1);
check!(ne, FOO as *const _, 0);
check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0);
check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0);
2020-07-30 05:27:34 -05:00
// 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!(!, FOO as *const _, FOO as *const _);
2020-07-30 05:27:34 -05:00
///////////////////////////////////////////////////////////////////////////////
// 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]) };
2021-06-18 12:31:56 -05:00
//~^ ERROR evaluation of constant value failed
//~| out-of-bounds
2020-07-30 05:27:34 -05:00
const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 };
2022-09-21 06:05:20 -05:00
//~^ ERROR evaluation of constant value failed
2021-07-12 17:21:35 -05:00
//~| unable to turn pointer into raw bytes
2020-07-30 05:27:34 -05:00
const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 };
2022-09-21 06:05:20 -05:00
//~^ ERROR evaluation of constant value failed
2021-07-12 17:21:35 -05:00
//~| unable to turn pointer into raw bytes