2022-07-24 14:23:39 -05:00
|
|
|
//@compile-flags: -Zmiri-permissive-provenance
|
|
|
|
#![feature(ptr_metadata, const_raw_ptr_comparison)]
|
2022-07-18 09:38:26 -05:00
|
|
|
|
|
|
|
use std::mem::{self, transmute};
|
|
|
|
use std::ptr;
|
2022-07-05 20:11:48 -05:00
|
|
|
|
2016-03-13 15:36:25 -05:00
|
|
|
fn one_line_ref() -> i16 {
|
|
|
|
*&1
|
|
|
|
}
|
2016-03-12 21:32:24 -06:00
|
|
|
|
2016-03-13 15:36:25 -05:00
|
|
|
fn basic_ref() -> i16 {
|
|
|
|
let x = &1;
|
|
|
|
*x
|
|
|
|
}
|
2016-03-12 21:32:24 -06:00
|
|
|
|
2016-03-13 15:36:25 -05:00
|
|
|
fn basic_ref_mut() -> i16 {
|
|
|
|
let x = &mut 1;
|
|
|
|
*x += 2;
|
|
|
|
*x
|
|
|
|
}
|
2016-03-12 21:32:24 -06:00
|
|
|
|
2016-03-13 15:36:25 -05:00
|
|
|
fn basic_ref_mut_var() -> i16 {
|
|
|
|
let mut a = 1;
|
|
|
|
{
|
|
|
|
let x = &mut a;
|
|
|
|
*x += 2;
|
|
|
|
}
|
|
|
|
a
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tuple_ref_mut() -> (i8, i8) {
|
|
|
|
let mut t = (10, 20);
|
|
|
|
{
|
|
|
|
let x = &mut t.1;
|
|
|
|
*x += 2;
|
|
|
|
}
|
|
|
|
t
|
|
|
|
}
|
|
|
|
|
|
|
|
fn match_ref_mut() -> i8 {
|
|
|
|
let mut t = (20, 22);
|
|
|
|
{
|
2017-08-12 11:45:44 -05:00
|
|
|
let opt = Some(&mut t);
|
2016-03-13 15:36:25 -05:00
|
|
|
match opt {
|
|
|
|
Some(&mut (ref mut x, ref mut y)) => *x += *y,
|
2022-06-20 18:00:37 -05:00
|
|
|
None => {}
|
2016-03-13 15:36:25 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
t.0
|
|
|
|
}
|
2016-04-07 04:07:57 -05:00
|
|
|
|
|
|
|
fn dangling_pointer() -> *const i32 {
|
2018-09-15 10:12:48 -05:00
|
|
|
let b = Box::new((42, 42)); // make it bigger than the alignment, so that there is some "room" after this pointer
|
|
|
|
&b.0 as *const i32
|
2016-04-07 04:07:57 -05:00
|
|
|
}
|
2016-04-22 03:34:14 -05:00
|
|
|
|
2022-07-05 20:11:48 -05:00
|
|
|
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));
|
|
|
|
}
|
|
|
|
|
2022-07-18 09:38:26 -05:00
|
|
|
fn metadata_vtable() {
|
|
|
|
let p = &0i32 as &dyn std::fmt::Debug;
|
|
|
|
let meta: ptr::DynMetadata<_> = ptr::metadata(p as *const _);
|
|
|
|
assert_eq!(meta.size_of(), mem::size_of::<i32>());
|
|
|
|
assert_eq!(meta.align_of(), mem::align_of::<i32>());
|
|
|
|
|
|
|
|
type T = [i32; 16];
|
|
|
|
let p = &T::default() as &dyn std::fmt::Debug;
|
|
|
|
let meta: ptr::DynMetadata<_> = ptr::metadata(p as *const _);
|
|
|
|
assert_eq!(meta.size_of(), mem::size_of::<T>());
|
|
|
|
assert_eq!(meta.align_of(), mem::align_of::<T>());
|
|
|
|
}
|
|
|
|
|
2016-04-22 07:38:46 -05:00
|
|
|
fn main() {
|
|
|
|
assert_eq!(one_line_ref(), 1);
|
|
|
|
assert_eq!(basic_ref(), 1);
|
|
|
|
assert_eq!(basic_ref_mut(), 3);
|
|
|
|
assert_eq!(basic_ref_mut_var(), 3);
|
|
|
|
assert_eq!(tuple_ref_mut(), (10, 22));
|
|
|
|
assert_eq!(match_ref_mut(), 42);
|
2018-09-15 09:35:37 -05:00
|
|
|
|
2018-09-15 10:12:48 -05:00
|
|
|
// Compare even dangling pointers with NULL, and with others in the same allocation, including
|
|
|
|
// out-of-bounds.
|
2016-04-22 07:38:46 -05:00
|
|
|
assert!(dangling_pointer() != std::ptr::null());
|
2022-06-20 18:00:37 -05:00
|
|
|
assert!(match dangling_pointer() as usize {
|
|
|
|
0 => false,
|
|
|
|
_ => true,
|
|
|
|
});
|
2018-09-15 09:35:37 -05:00
|
|
|
let dangling = dangling_pointer();
|
|
|
|
assert!(dangling == dangling);
|
|
|
|
assert!(dangling.wrapping_add(1) != dangling);
|
2018-09-15 10:12:48 -05:00
|
|
|
assert!(dangling.wrapping_sub(1) != dangling);
|
|
|
|
|
|
|
|
// Compare pointer with BIG integers
|
|
|
|
let dangling = dangling as usize;
|
|
|
|
assert!(dangling != usize::MAX);
|
|
|
|
assert!(dangling != usize::MAX - 1);
|
|
|
|
assert!(dangling != usize::MAX - 2);
|
|
|
|
assert!(dangling != usize::MAX - 3); // this is even 4-aligned, but it still cannot be equal because of the extra "room" after this pointer
|
|
|
|
assert_eq!((usize::MAX - 3) % 4, 0); // just to be sure we got this right
|
|
|
|
|
|
|
|
// Compare pointer with unaligned integers
|
|
|
|
assert!(dangling != 1usize);
|
|
|
|
assert!(dangling != 2usize);
|
|
|
|
assert!(dangling != 3usize);
|
|
|
|
// 4 is a possible choice! So we cannot compare with that.
|
|
|
|
assert!(dangling != 5usize);
|
|
|
|
assert!(dangling != 6usize);
|
|
|
|
assert!(dangling != 7usize);
|
2019-06-20 09:38:55 -05:00
|
|
|
|
|
|
|
// Using inequality to do the comparison.
|
|
|
|
assert!(dangling > 0);
|
|
|
|
assert!(dangling > 1);
|
|
|
|
assert!(dangling > 2);
|
|
|
|
assert!(dangling > 3);
|
|
|
|
assert!(dangling >= 4);
|
2022-07-05 20:11:48 -05:00
|
|
|
|
2022-07-24 14:23:39 -05:00
|
|
|
// CTFE-specific equality tests, need to also work at runtime.
|
|
|
|
let addr = &13 as *const i32;
|
|
|
|
let addr2 = (addr as usize).wrapping_add(usize::MAX).wrapping_add(1);
|
2022-09-10 08:56:05 -05:00
|
|
|
assert_eq!(addr.guaranteed_eq(addr2 as *const _), Some(true));
|
|
|
|
assert_eq!(addr.guaranteed_ne(0x100 as *const _), Some(true));
|
2022-07-24 14:23:39 -05:00
|
|
|
|
2022-07-05 20:11:48 -05:00
|
|
|
wide_ptr_ops();
|
2022-07-18 09:38:26 -05:00
|
|
|
metadata_vtable();
|
2016-04-22 07:38:46 -05:00
|
|
|
}
|