]>
Commit | Line | Data |
---|---|---|
3dfed10e XL |
1 | // compile-flags: --crate-type=lib |
2 | // normalize-stderr-32bit: "offset 8" -> "offset $$TWO_WORDS" | |
3 | // normalize-stderr-64bit: "offset 16" -> "offset $$TWO_WORDS" | |
4 | // normalize-stderr-32bit: "size 4" -> "size $$WORD" | |
5 | // normalize-stderr-64bit: "size 8" -> "size $$WORD" | |
6 | ||
7 | #![feature( | |
8 | const_panic, | |
9 | core_intrinsics, | |
10 | const_raw_ptr_comparison, | |
11 | const_ptr_offset, | |
5869c6ff | 12 | const_raw_ptr_deref |
3dfed10e XL |
13 | )] |
14 | ||
15 | const FOO: &usize = &42; | |
16 | ||
17 | macro_rules! check { | |
18 | (eq, $a:expr, $b:expr) => { | |
19 | pub const _: () = | |
20 | assert!(std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8)); | |
21 | }; | |
22 | (ne, $a:expr, $b:expr) => { | |
23 | pub const _: () = | |
24 | assert!(std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8)); | |
25 | }; | |
26 | (!eq, $a:expr, $b:expr) => { | |
27 | pub const _: () = | |
28 | assert!(!std::intrinsics::ptr_guaranteed_eq($a as *const u8, $b as *const u8)); | |
29 | }; | |
30 | (!ne, $a:expr, $b:expr) => { | |
31 | pub const _: () = | |
32 | assert!(!std::intrinsics::ptr_guaranteed_ne($a as *const u8, $b as *const u8)); | |
33 | }; | |
34 | } | |
35 | ||
36 | check!(eq, 0, 0); | |
37 | check!(ne, 0, 1); | |
38 | check!(!eq, 0, 1); | |
39 | check!(!ne, 0, 0); | |
40 | check!(ne, FOO as *const _, 0); | |
41 | check!(!eq, FOO as *const _, 0); | |
42 | // We want pointers to be equal to themselves, but aren't checking this yet because | |
43 | // there are some open questions (e.g. whether function pointers to the same function | |
44 | // compare equal, they don't necessarily at runtime). | |
45 | // The case tested here should work eventually, but does not work yet. | |
46 | check!(!eq, FOO as *const _, FOO as *const _); | |
47 | check!(ne, unsafe { (FOO as *const usize).offset(1) }, 0); | |
48 | check!(!eq, unsafe { (FOO as *const usize).offset(1) }, 0); | |
49 | ||
50 | check!(ne, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0); | |
51 | check!(!eq, unsafe { (FOO as *const usize as *const u8).offset(3) }, 0); | |
52 | ||
53 | /////////////////////////////////////////////////////////////////////////////// | |
54 | // If any of the below start compiling, make sure to add a `check` test for it. | |
55 | // These invocations exist as canaries so we don't forget to check that the | |
56 | // behaviour of `guaranteed_eq` and `guaranteed_ne` is still correct. | |
57 | // All of these try to obtain an out of bounds pointer in some manner. If we | |
58 | // can create out of bounds pointers, we can offset a pointer far enough that | |
59 | // at runtime it would be zero and at compile-time it would not be zero. | |
60 | ||
61 | const _: *const usize = unsafe { (FOO as *const usize).offset(2) }; | |
62 | //~^ NOTE | |
63 | ||
64 | const _: *const u8 = | |
65 | //~^ NOTE | |
5869c6ff | 66 | unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) }; |
3dfed10e | 67 | //~^ ERROR any use of this value will cause an error |
5869c6ff XL |
68 | //~| NOTE |
69 | //~| WARN this was previously accepted by the compiler but is being phased out | |
70 | //~| NOTE | |
3dfed10e XL |
71 | |
72 | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 }; | |
73 | //~^ ERROR any use of this value will cause an error | |
74 | //~| NOTE "pointer-to-integer cast" needs an rfc | |
75 | //~| NOTE | |
5869c6ff XL |
76 | //~| WARN this was previously accepted by the compiler but is being phased out |
77 | //~| NOTE | |
3dfed10e XL |
78 | |
79 | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 }; | |
80 | //~^ ERROR any use of this value will cause an error | |
81 | //~| NOTE "pointer-to-integer cast" needs an rfc | |
82 | //~| NOTE | |
5869c6ff XL |
83 | //~| WARN this was previously accepted by the compiler but is being phased out |
84 | //~| NOTE |