]> git.lizzy.rs Git - rust.git/blob - src/test/ui/const-ptr/forbidden_slices.rs
Rollup merge of #100861 - RalfJung:const-ice, r=oli-obk
[rust.git] / src / test / ui / const-ptr / forbidden_slices.rs
1 // stderr-per-bitwidth
2 // normalize-stderr-test "alloc[0-9]+" -> "ALLOC_ID"
3 // normalize-stderr-test "a[0-9]+\+0x" -> "A_ID+0x"
4 // error-pattern: could not evaluate static initializer
5 #![feature(
6     slice_from_ptr_range,
7     const_slice_from_ptr_range,
8     pointer_byte_offsets,
9     const_pointer_byte_offsets
10 )]
11 use std::{
12     mem::{size_of, MaybeUninit},
13     ptr,
14     slice::{from_ptr_range, from_raw_parts},
15 };
16
17 // Null is never valid for reads
18 pub static S0: &[u32] = unsafe { from_raw_parts(ptr::null(), 0) };
19 pub static S1: &[()] = unsafe { from_raw_parts(ptr::null(), 0) };
20
21 // Out of bounds
22 pub static S2: &[u32] = unsafe { from_raw_parts(&D0, 2) };
23
24 // Reading uninitialized  data
25 pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) }; //~ ERROR: it is undefined behavior to use this value
26 // Reinterpret pointers as integers (UB in CTFE.)
27 pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, size_of::<&u32>()) }; //~ ERROR: it is undefined behavior to use this value
28 // Layout mismatch
29 pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) }; //~ ERROR: it is undefined behavior to use this value
30
31 // Reading padding is not ok
32 pub static S7: &[u16] = unsafe {
33     //~^ ERROR: it is undefined behavior to use this value
34     let ptr = (&D2 as *const Struct as *const u16).byte_add(1);
35
36     from_raw_parts(ptr, 4)
37 };
38
39 // Unaligned read
40 pub static S8: &[u64] = unsafe {
41     let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::<u64>();
42
43     from_raw_parts(ptr, 1)
44 };
45
46 pub static R0: &[u32] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
47 pub static R1: &[()] = unsafe { from_ptr_range(ptr::null()..ptr::null()) };
48 pub static R2: &[u32] = unsafe {
49     let ptr = &D0 as *const u32;
50     from_ptr_range(ptr..ptr.add(2))
51 };
52 pub static R4: &[u8] = unsafe {
53     //~^ ERROR: it is undefined behavior to use this value
54     let ptr = (&D1) as *const MaybeUninit<&u32> as *const u8;
55     from_ptr_range(ptr..ptr.add(1))
56 };
57 pub static R5: &[u8] = unsafe {
58     //~^ ERROR: it is undefined behavior to use this value
59     let ptr = &D3 as *const &u32;
60     from_ptr_range(ptr.cast()..ptr.add(1).cast())
61 };
62 pub static R6: &[bool] = unsafe {
63     //~^ ERROR: it is undefined behavior to use this value
64     let ptr = &D0 as *const u32 as *const bool;
65     from_ptr_range(ptr..ptr.add(4))
66 };
67 pub static R7: &[u16] = unsafe {
68     //~^ ERROR: it is undefined behavior to use this value
69     let ptr = (&D2 as *const Struct as *const u16).byte_add(1);
70     from_ptr_range(ptr..ptr.add(4))
71 };
72 pub static R8: &[u64] = unsafe {
73     let ptr = (&D4 as *const [u32; 2] as *const u32).byte_add(1).cast::<u64>();
74     from_ptr_range(ptr..ptr.add(1))
75 };
76
77 // This is sneaky: &D0 and &D0 point to different objects
78 // (even if at runtime they have the same address)
79 pub static R9: &[u32] = unsafe { from_ptr_range(&D0..(&D0 as *const u32).add(1)) };
80 pub static R10: &[u32] = unsafe { from_ptr_range(&D0..&D0) };
81
82 const D0: u32 = 0x11;
83 const D1: MaybeUninit<&u32> = MaybeUninit::uninit();
84 const D2: Struct = Struct { a: 1, b: 2, c: 3, d: 4 };
85 const D3: &u32 = &42;
86 const D4: [u32; 2] = [17, 42];
87
88 #[repr(C)]
89 struct Struct {
90     a: u8,
91     // _pad: [MaybeUninit<u8>; 3]
92     b: u32,
93     c: u16,
94     d: u8,
95     // _pad: [MaybeUninit<u8>; 1]
96 }
97
98 fn main() {}