about summary refs log tree commit diff
path: root/src/tools/miri/tests/pass/ptr_int_casts.rs
blob: 94391eac3b2748107795135282637f658ff2a265 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//@compile-flags: -Zmiri-permissive-provenance
use std::{mem, ptr};

fn eq_ref<T>(x: &T, y: &T) -> bool {
    x as *const _ == y as *const _
}

fn f() -> i32 {
    42
}

fn ptr_int_casts() {
    // int-ptr-int
    assert_eq!(1 as *const i32 as usize, 1);
    assert_eq!((1 as *const i32).wrapping_offset(4) as usize, 1 + 4 * 4);

    // 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);
    assert_eq!(*val as usize, usize::MAX - 2);

    // ptr-int-ptr
    {
        let x = 13;
        let mut y = &x as &_ as *const _ as usize;
        y += 13;
        y -= 13;
        let y = y as *const _;
        assert!(eq_ref(&x, unsafe { &*y }));
    }

    // fnptr-int-fnptr
    {
        let x: fn() -> i32 = f;
        let y: *mut u8 = unsafe { mem::transmute(x as fn() -> i32) };
        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);
    }

    // involving types other than usize
    assert_eq!((-1i32) as usize as *const i32 as usize, (-1i32) as usize);
}

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();
}