2017-06-21 23:38:43 -05:00
|
|
|
use std::mem;
|
2019-05-26 07:47:37 -05:00
|
|
|
use std::ptr;
|
2017-06-21 23:38:43 -05:00
|
|
|
|
2017-06-05 17:18:40 -05:00
|
|
|
fn eq_ref<T>(x: &T, y: &T) -> bool {
|
|
|
|
x as *const _ == y as *const _
|
|
|
|
}
|
2017-06-04 12:42:02 -05:00
|
|
|
|
2017-06-21 23:38:43 -05:00
|
|
|
fn f() -> i32 { 42 }
|
|
|
|
|
2020-04-16 02:06:21 -05:00
|
|
|
fn ptr_int_casts() {
|
2017-06-04 12:42:02 -05:00
|
|
|
// int-ptr-int
|
|
|
|
assert_eq!(1 as *const i32 as usize, 1);
|
2017-06-21 23:38:43 -05:00
|
|
|
assert_eq!((1 as *const i32).wrapping_offset(4) as usize, 1 + 4*4);
|
2017-06-04 12:42:02 -05:00
|
|
|
|
2019-05-26 07:47:37 -05:00
|
|
|
// negative overflowing wrapping_offset (going through memory because
|
|
|
|
// this used to trigger an ICE on 32bit)
|
|
|
|
let val = &mut ptr::null();
|
|
|
|
*val = (1 as *const u8).wrapping_offset(-4);
|
2020-03-04 06:01:06 -06:00
|
|
|
assert_eq!(*val as usize, usize::MAX - 2);
|
2019-05-26 07:47:37 -05:00
|
|
|
|
2017-06-05 17:18:40 -05:00
|
|
|
{ // ptr-int-ptr
|
|
|
|
let x = 13;
|
2017-06-23 00:56:49 -05:00
|
|
|
let mut y = &x as &_ as *const _ as usize;
|
2017-06-21 23:38:43 -05:00
|
|
|
y += 13;
|
|
|
|
y -= 13;
|
2017-06-05 17:18:40 -05:00
|
|
|
let y = y as *const _;
|
|
|
|
assert!(eq_ref(&x, unsafe { &*y }));
|
|
|
|
}
|
2017-06-21 23:38:43 -05:00
|
|
|
|
|
|
|
{ // fnptr-int-fnptr
|
|
|
|
let x : fn() -> i32 = f;
|
2017-06-23 00:56:49 -05:00
|
|
|
let y : *mut u8 = unsafe { mem::transmute(x as fn() -> i32) };
|
2017-06-21 23:38:43 -05:00
|
|
|
let mut y = y as usize;
|
|
|
|
y += 13;
|
|
|
|
y -= 13;
|
|
|
|
let x : fn() -> i32 = unsafe { mem::transmute(y as *mut u8) };
|
|
|
|
assert_eq!(x(), 42);
|
|
|
|
}
|
2017-07-20 15:52:58 -05:00
|
|
|
|
|
|
|
// involving types other than usize
|
|
|
|
assert_eq!((-1i32) as usize as *const i32 as usize, (-1i32) as usize);
|
2017-06-04 12:42:02 -05:00
|
|
|
}
|
2020-04-16 02:06:21 -05:00
|
|
|
|
|
|
|
fn ptr_int_ops() {
|
|
|
|
let v = [1i16, 2];
|
|
|
|
let x = &v[1] as *const i16 as usize;
|
|
|
|
// arithmetic
|
|
|
|
let _y = x + 4;
|
|
|
|
let _y = 4 + x;
|
|
|
|
let _y = x - 2;
|
|
|
|
// bit-operations, covered by alignment
|
|
|
|
assert_eq!(x & 1, 0);
|
|
|
|
assert_eq!(x & 0, 0);
|
|
|
|
assert_eq!(1 & (x+1), 1);
|
|
|
|
let _y = !1 & x;
|
|
|
|
let _y = !0 & x;
|
|
|
|
let _y = x & !1;
|
|
|
|
// remainder, covered by alignment
|
|
|
|
assert_eq!(x % 2, 0);
|
|
|
|
assert_eq!((x+1) % 2, 1);
|
|
|
|
// remainder with 1 is always 0
|
|
|
|
assert_eq!(x % 1, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
ptr_int_casts();
|
|
|
|
ptr_int_ops();
|
|
|
|
}
|