|
| 1 | +// run-pass |
| 2 | +#![feature( |
| 3 | + const_slice_from_raw_parts, |
| 4 | + slice_from_ptr_range, |
| 5 | + const_slice_from_ptr_range, |
| 6 | + pointer_byte_offsets, |
| 7 | + const_pointer_byte_offsets |
| 8 | +)] |
| 9 | +use std::{ |
| 10 | + mem::MaybeUninit, |
| 11 | + ptr, |
| 12 | + slice::{from_ptr_range, from_raw_parts}, |
| 13 | +}; |
| 14 | + |
| 15 | +// Dangling is ok, as long as it's either for ZST reads or for no reads |
| 16 | +pub static S0: &[u32] = unsafe { from_raw_parts(dangling(), 0) }; |
| 17 | +pub static S1: &[()] = unsafe { from_raw_parts(dangling(), 3) }; |
| 18 | + |
| 19 | +// References are always valid of reads of a single element (basically `slice::from_ref`) |
| 20 | +pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 1) }; |
| 21 | +pub static S3: &[MaybeUninit<&u32>] = unsafe { from_raw_parts(&D1, 1) }; |
| 22 | + |
| 23 | +// Reinterpreting data is fine, as long as layouts match |
| 24 | +pub static S4: &[u8] = unsafe { from_raw_parts((&D0) as *const _ as _, 3) }; |
| 25 | +// This is only valid because D1 has uninitialized bytes, if it was an initialized pointer, |
| 26 | +// that would reinterpret pointers as integers which is UB in CTFE. |
| 27 | +pub static S5: &[MaybeUninit<u8>] = unsafe { from_raw_parts((&D1) as *const _ as _, 2) }; |
| 28 | +// Even though u32 and [bool; 4] have different layouts, D0 has a value that |
| 29 | +// is valid as [bool; 4], so this is not UB (it's basically a transmute) |
| 30 | +pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; |
| 31 | + |
| 32 | +// Structs are considered single allocated objects, |
| 33 | +// as long as you don't reinterpret padding as initialized |
| 34 | +// data everything is ok. |
| 35 | +pub static S7: &[u16] = unsafe { |
| 36 | + let ptr = (&D2 as *const Struct as *const u16).byte_add(4); |
| 37 | + |
| 38 | + from_raw_parts(ptr, 3) |
| 39 | +}; |
| 40 | +pub static S8: &[MaybeUninit<u16>] = unsafe { |
| 41 | + let ptr = &D2 as *const Struct as *const MaybeUninit<u16>; |
| 42 | + |
| 43 | + from_raw_parts(ptr, 6) |
| 44 | +}; |
| 45 | + |
| 46 | +pub static R0: &[u32] = unsafe { from_ptr_range(dangling()..dangling()) }; |
| 47 | +// from_ptr_range panics on zst |
| 48 | +//pub static R1: &[()] = unsafe { from_ptr_range(dangling(), dangling().byte_add(3)) }; |
| 49 | +pub static R2: &[u32] = unsafe { |
| 50 | + let ptr = &D0 as *const u32; |
| 51 | + from_ptr_range(ptr..ptr.add(1)) |
| 52 | +}; |
| 53 | +pub static R3: &[MaybeUninit<&u32>] = unsafe { |
| 54 | + let ptr = &D1 as *const MaybeUninit<&u32>; |
| 55 | + from_ptr_range(ptr..ptr.add(1)) |
| 56 | +}; |
| 57 | +pub static R4: &[u8] = unsafe { |
| 58 | + let ptr = &D0 as *const u32 as *const u8; |
| 59 | + from_ptr_range(ptr..ptr.add(3)) |
| 60 | +}; |
| 61 | +pub static R5: &[MaybeUninit<u8>] = unsafe { |
| 62 | + let ptr = &D1 as *const MaybeUninit<&u32> as *const MaybeUninit<u8>; |
| 63 | + from_ptr_range(ptr..ptr.add(2)) |
| 64 | +}; |
| 65 | +pub static R6: &[bool] = unsafe { |
| 66 | + let ptr = &D0 as *const u32 as *const bool; |
| 67 | + from_ptr_range(ptr..ptr.add(4)) |
| 68 | +}; |
| 69 | +pub static R7: &[u16] = unsafe { |
| 70 | + let d2 = &D2; |
| 71 | + let l = &d2.b as *const u32 as *const u16; |
| 72 | + let r = &d2.d as *const u8 as *const u16; |
| 73 | + |
| 74 | + from_ptr_range(l..r) |
| 75 | +}; |
| 76 | +pub static R8: &[MaybeUninit<u16>] = unsafe { |
| 77 | + let d2 = &D2; |
| 78 | + let l = d2 as *const Struct as *const MaybeUninit<u16>; |
| 79 | + let r = &d2.d as *const u8 as *const MaybeUninit<u16>; |
| 80 | + |
| 81 | + from_ptr_range(l..r) |
| 82 | +}; |
| 83 | + |
| 84 | +// Using valid slice is always valid |
| 85 | +pub static R9: &[u32] = unsafe { from_ptr_range(R0.as_ptr_range()) }; |
| 86 | +pub static R10: &[u32] = unsafe { from_ptr_range(R2.as_ptr_range()) }; |
| 87 | + |
| 88 | +const D0: u32 = (1 << 16) | 1; |
| 89 | +const D1: MaybeUninit<&u32> = MaybeUninit::uninit(); |
| 90 | +const D2: Struct = Struct { a: 1, b: 2, c: 3, d: 4 }; |
| 91 | + |
| 92 | +const fn dangling<T>() -> *const T { |
| 93 | + ptr::NonNull::dangling().as_ptr() as _ |
| 94 | +} |
| 95 | + |
| 96 | +#[repr(C)] |
| 97 | +struct Struct { |
| 98 | + a: u8, |
| 99 | + // _pad: [MaybeUninit<u8>; 3] |
| 100 | + b: u32, |
| 101 | + c: u16, |
| 102 | + d: u8, |
| 103 | + // _pad: [MaybeUninit<u8>; 1] |
| 104 | +} |
| 105 | + |
| 106 | +fn main() {} |
0 commit comments