From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/const-ptr/allowed_slices.rs | 105 +++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 tests/ui/const-ptr/allowed_slices.rs (limited to 'tests/ui/const-ptr/allowed_slices.rs') diff --git a/tests/ui/const-ptr/allowed_slices.rs b/tests/ui/const-ptr/allowed_slices.rs new file mode 100644 index 000000000..3f19cd4d8 --- /dev/null +++ b/tests/ui/const-ptr/allowed_slices.rs @@ -0,0 +1,105 @@ +// run-pass +#![feature( + slice_from_ptr_range, + const_slice_from_ptr_range, + pointer_byte_offsets, + const_pointer_byte_offsets +)] +use std::{ + mem::MaybeUninit, + ptr, + slice::{from_ptr_range, from_raw_parts}, +}; + +// Dangling is ok, as long as it's either for ZST reads or for no reads +pub static S0: &[u32] = unsafe { from_raw_parts(dangling(), 0) }; +pub static S1: &[()] = unsafe { from_raw_parts(dangling(), 3) }; + +// References are always valid of reads of a single element (basically `slice::from_ref`) +pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 1) }; +pub static S3: &[MaybeUninit<&u32>] = unsafe { from_raw_parts(&D1, 1) }; + +// Reinterpreting data is fine, as long as layouts match +pub static S4: &[u8] = unsafe { from_raw_parts((&D0) as *const _ as _, 3) }; +// This is only valid because D1 has uninitialized bytes, if it was an initialized pointer, +// that would reinterpret pointers as integers which is UB in CTFE. +pub static S5: &[MaybeUninit] = unsafe { from_raw_parts((&D1) as *const _ as _, 2) }; +// Even though u32 and [bool; 4] have different layouts, D0 has a value that +// is valid as [bool; 4], so this is not UB (it's basically a transmute) +pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; + +// Structs are considered single allocated objects, +// as long as you don't reinterpret padding as initialized +// data everything is ok. +pub static S7: &[u16] = unsafe { + let ptr = (&D2 as *const Struct as *const u16).byte_add(4); + + from_raw_parts(ptr, 3) +}; +pub static S8: &[MaybeUninit] = unsafe { + let ptr = &D2 as *const Struct as *const MaybeUninit; + + from_raw_parts(ptr, 6) +}; + +pub static R0: &[u32] = unsafe { from_ptr_range(dangling()..dangling()) }; +// from_ptr_range panics on zst +//pub static R1: &[()] = unsafe { from_ptr_range(dangling(), dangling().byte_add(3)) }; +pub static R2: &[u32] = unsafe { + let ptr = &D0 as *const u32; + from_ptr_range(ptr..ptr.add(1)) +}; +pub static R3: &[MaybeUninit<&u32>] = unsafe { + let ptr = &D1 as *const MaybeUninit<&u32>; + from_ptr_range(ptr..ptr.add(1)) +}; +pub static R4: &[u8] = unsafe { + let ptr = &D0 as *const u32 as *const u8; + from_ptr_range(ptr..ptr.add(3)) +}; +pub static R5: &[MaybeUninit] = unsafe { + let ptr = &D1 as *const MaybeUninit<&u32> as *const MaybeUninit; + from_ptr_range(ptr..ptr.add(2)) +}; +pub static R6: &[bool] = unsafe { + let ptr = &D0 as *const u32 as *const bool; + from_ptr_range(ptr..ptr.add(4)) +}; +pub static R7: &[u16] = unsafe { + let d2 = &D2; + let l = &d2.b as *const u32 as *const u16; + let r = &d2.d as *const u8 as *const u16; + + from_ptr_range(l..r) +}; +pub static R8: &[MaybeUninit] = unsafe { + let d2 = &D2; + let l = d2 as *const Struct as *const MaybeUninit; + let r = &d2.d as *const u8 as *const MaybeUninit; + + from_ptr_range(l..r) +}; + +// Using valid slice is always valid +pub static R9: &[u32] = unsafe { from_ptr_range(R0.as_ptr_range()) }; +pub static R10: &[u32] = unsafe { from_ptr_range(R2.as_ptr_range()) }; + +const D0: u32 = (1 << 16) | 1; +const D1: MaybeUninit<&u32> = MaybeUninit::uninit(); +const D2: Struct = Struct { a: 1, b: 2, c: 3, d: 4 }; + +const fn dangling() -> *const T { + ptr::NonNull::dangling().as_ptr() as _ +} + +#[repr(C)] +struct Struct { + a: u8, + // _pad: [MaybeUninit; 3] + b: u32, + c: u16, + d: u8, + // _pad: [MaybeUninit; 1] +} + +fn main() {} -- cgit v1.2.3