summaryrefslogtreecommitdiffstats
path: root/src/test/ui/const-ptr/forbidden_slices.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/const-ptr/forbidden_slices.rs')
-rw-r--r--src/test/ui/const-ptr/forbidden_slices.rs98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/test/ui/const-ptr/forbidden_slices.rs b/src/test/ui/const-ptr/forbidden_slices.rs
new file mode 100644
index 000000000..e2184911f
--- /dev/null
+++ b/src/test/ui/const-ptr/forbidden_slices.rs
@@ -0,0 +1,98 @@
+// stderr-per-bitwidth
+// normalize-stderr-test "alloc[0-9]+" -> "ALLOC_ID"
+// normalize-stderr-test "a[0-9]+\+0x" -> "A_ID+0x"
+// error-pattern: could not evaluate static initializer
+#![feature(
+ slice_from_ptr_range,
+ const_slice_from_ptr_range,
+ pointer_byte_offsets,
+ const_pointer_byte_offsets
+)]
+use std::{
+ mem::{size_of, MaybeUninit},
+ ptr,
+ slice::{from_ptr_range, from_raw_parts},
+};
+
+// Null is never valid for reads
+pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) };
+pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) };
+
+// Out of bounds
+pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) };
+
+// Reading uninitialized data
+pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; //~ ERROR: it is undefined behavior to use this value
+// Reinterpret pointers as integers (UB in CTFE.)
+pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size_of::<&u32>()) }; //~ ERROR: it is undefined behavior to use this value
+// Layout mismatch
+pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; //~ ERROR: it is undefined behavior to use this value
+
+// Reading padding is not ok
+pub static S7: &[u16] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = (&D2 as *const Struct as *const u16).byte_add(1);
+
+ from_raw_parts(ptr, 4)
+};
+
+// Unaligned read
+pub static S8: &[u64] = unsafe {
+ let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::<u64>();
+
+ from_raw_parts(ptr, 1)
+};
+
+pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
+pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
+pub static R2: &[u32] = unsafe {
+ let ptr = &D0 as *const u32;
+ from_ptr_range(ptr..ptr.add(2))
+};
+pub static R4: &[u8] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = (&D1) as *const MaybeUninit<&u32> as *const u8;
+ from_ptr_range(ptr..ptr.add(1))
+};
+pub static R5: &[u8] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = &D3 as *const &u32;
+ from_ptr_range(ptr.cast()..ptr.add(1).cast())
+};
+pub static R6: &[bool] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = &D0 as *const u32 as *const bool;
+ from_ptr_range(ptr..ptr.add(4))
+};
+pub static R7: &[u16] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = (&D2 as *const Struct as *const u16).byte_add(1);
+ from_ptr_range(ptr..ptr.add(4))
+};
+pub static R8: &[u64] = unsafe {
+ let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::<u64>();
+ from_ptr_range(ptr..ptr.add(1))
+};
+
+// This is sneaky: &D0 and &D0 point to different objects
+// (even if at runtime they have the same address)
+pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) };
+pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) };
+
+const D0: u32 = 0x11;
+const D1: MaybeUninit<&u32> = MaybeUninit::uninit();
+const D2: Struct = Struct { a: 1, b: 2, c: 3, d: 4 };
+const D3: &u32 = &42;
+const D4: [u32; 2] = [17, 42];
+
+#[repr(C)]
+struct Struct {
+ a: u8,
+ // _pad: [MaybeUninit<u8>; 3]
+ b: u32,
+ c: u16,
+ d: u8,
+ // _pad: [MaybeUninit<u8>; 1]
+}
+
+fn main() {}