about summary refs log tree commit diff
path: root/tests/ui/consts/const-eval/ptr_fragments.rs
blob: 7dc5870f89e2b76a8a5d11269cf396c4948a5810 (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
//! Test that various operations involving pointer fragments work as expected.
//@ run-pass
//@ ignore-test: disabled due to <https://github.com/rust-lang/rust/issues/146291>

use std::mem::{self, MaybeUninit, transmute};
use std::ptr;

type Byte = MaybeUninit<u8>;

const unsafe fn memcpy(dst: *mut Byte, src: *const Byte, n: usize) {
    let mut i = 0;
    while i < n {
        *dst.add(i) = *src.add(i);
        i += 1;
    }
}

const _MEMCPY: () = unsafe {
    let ptr = &42;
    let mut ptr2 = ptr::null::<i32>();
    memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>());
    assert!(*ptr2 == 42);
};
const _MEMCPY_OFFSET: () = unsafe {
    // Same as above, but the pointer has a non-zero offset so not all the data bytes are the same.
    let ptr = &(42, 18);
    let ptr = &ptr.1;
    let mut ptr2 = ptr::null::<i32>();
    memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>());
    assert!(*ptr2 == 18);
};

const MEMCPY_RET: MaybeUninit<*const i32> = unsafe {
    let ptr = &42;
    let mut ptr2 = MaybeUninit::new(ptr::null::<i32>());
    memcpy(&mut ptr2 as *mut _ as *mut _, &ptr as *const _ as *const _, mem::size_of::<&i32>());
    // Return in a MaybeUninit so it does not get treated as a scalar.
    ptr2
};

#[allow(dead_code)]
fn reassemble_ptr_fragments_in_static() {
    static DATA: i32 = 1i32;

    #[cfg(target_pointer_width = "64")]
    struct Thing {
        x: MaybeUninit<u32>,
        y: MaybeUninit<u32>,
    }
    #[cfg(target_pointer_width = "32")]
    struct Thing {
        x: MaybeUninit<u16>,
        y: MaybeUninit<u16>,
    }

    static X: Thing = unsafe {
        let Thing { x, y } = transmute(&raw const DATA);
        Thing { x, y }
    };
}

fn main() {
    assert_eq!(unsafe { MEMCPY_RET.assume_init().read() }, 42);
}