]> git.lizzy.rs Git - rust.git/blob - src/test/ui/consts/const-eval/raw-bytes.rs
Rollup merge of #106175 - compiler-errors:bad-import-sugg, r=oli-obk
[rust.git] / src / test / ui / consts / const-eval / raw-bytes.rs
1 // stderr-per-bitwidth
2 // ignore-endian-big
3 // ignore-tidy-linelength
4 // normalize-stderr-test "╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼" -> "╾ALLOC_ID$2╼"
5 // normalize-stderr-test "alloc\d+" -> "allocN"
6 #![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)]
7 #![allow(invalid_value)]
8
9 use std::mem;
10 use std::alloc::Layout;
11 use std::ptr::NonNull;
12 use std::num::{NonZeroU8, NonZeroUsize};
13 use std::slice::{from_ptr_range, from_raw_parts};
14
15 #[repr(usize)]
16 #[derive(Copy, Clone)]
17 enum Enum {
18     A = 0,
19 }
20 const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
21 //~^ ERROR is undefined behavior
22
23 #[repr(usize)]
24 #[derive(Copy, Clone)]
25 enum Enum2 {
26     A = 2,
27 }
28 const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
29 //~^ ERROR is undefined behavior
30
31 #[derive(Copy, Clone)]
32 enum Never {}
33
34 // An enum with 3 variants of which some are uninhabited -- so the uninhabited variants *do*
35 // have a discriminant.
36 enum UninhDiscriminant {
37     A,
38     B(!),
39     C,
40     D(Never),
41 }
42 const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
43 //~^ ERROR is undefined behavior
44 const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
45 //~^ ERROR is undefined behavior
46
47 // Invalid enum field content (mostly to test printing of paths for enum tuple
48 // variants and tuples).
49 // Need to create something which does not clash with enum layout optimizations.
50 const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
51 //~^ ERROR is undefined behavior
52
53
54 const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
55 //~^ ERROR it is undefined behavior to use this value
56
57 const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
58 //~^ ERROR it is undefined behavior to use this value
59 const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
60 //~^ ERROR it is undefined behavior to use this value
61
62 #[rustc_layout_scalar_valid_range_start(10)]
63 #[rustc_layout_scalar_valid_range_end(30)]
64 struct RestrictedRange1(u32);
65 const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
66 //~^ ERROR it is undefined behavior to use this value
67
68 #[rustc_layout_scalar_valid_range_start(30)]
69 #[rustc_layout_scalar_valid_range_end(10)]
70 struct RestrictedRange2(u32);
71 const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
72 //~^ ERROR it is undefined behavior to use this value
73
74 const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
75 //~^ ERROR it is undefined behavior to use this value
76     let x: &dyn Send = &42;
77     let meta = std::ptr::metadata(x);
78     mem::transmute((0_usize, meta))
79 };
80
81
82 const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
83 //~^ ERROR it is undefined behavior to use this value
84 //~| constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
85
86 const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
87 //~^ ERROR it is undefined behavior to use this value
88 //~| constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
89
90 const NULL: &u16 = unsafe { mem::transmute(0usize) };
91 //~^ ERROR it is undefined behavior to use this value
92
93 const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
94 //~^ ERROR it is undefined behavior to use this value
95
96 const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
97 //~^ ERROR it is undefined behavior to use this value
98
99 const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
100 //~^ ERROR it is undefined behavior to use this value
101
102 const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
103 //~^ ERROR it is undefined behavior to use this value
104 const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
105 //~^ ERROR it is undefined behavior to use this value
106 const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
107 //~^ ERROR it is undefined behavior to use this value
108
109 #[derive(Copy, Clone)]
110 enum Bar {}
111
112 const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
113 //~^ ERROR it is undefined behavior to use this value
114
115
116 /// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error
117 /// message.
118 #[repr(transparent)]
119 struct W<T>(T);
120
121 #[repr(C)]
122 union MaybeUninit<T: Copy> {
123     uninit: (),
124     init: T,
125 }
126
127 trait Trait {}
128 impl Trait for bool {}
129
130 // custom unsized type
131 struct MyStr(str);
132
133 // custom unsized type with sized fields
134 struct MySlice<T: ?Sized>(bool, T);
135 type MySliceBool = MySlice<[bool]>;
136
137 const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
138 //~^ ERROR it is undefined behavior to use this value
139 const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
140 //~^ ERROR it is undefined behavior to use this value
141 const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
142 //~^ ERROR it is undefined behavior to use this value
143
144 const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
145 //~^ ERROR it is undefined behavior to use this value
146 const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
147 //~^ ERROR it is undefined behavior to use this value
148 const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
149 //~^ ERROR: it is undefined behavior to use this value
150
151 // # slice
152 const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
153 //~^ ERROR it is undefined behavior to use this value
154 const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
155 //~^ ERROR it is undefined behavior to use this value
156 // bad slice box: length too big
157 const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
158 //~^ ERROR it is undefined behavior to use this value
159 // bad data *inside* the slice
160 const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
161 //~^ ERROR it is undefined behavior to use this value
162 //~| constant
163
164
165 // bad: sized field is not okay
166 const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
167 //~^ ERROR it is undefined behavior to use this value
168 //~| constant
169 // bad: unsized part is not okay
170 const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
171 //~^ ERROR it is undefined behavior to use this value
172 //~| constant
173
174 // bad trait object
175 const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
176 //~^ ERROR it is undefined behavior to use this value
177 //~| expected a vtable
178 // bad trait object
179 const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
180 //~^ ERROR it is undefined behavior to use this value
181 //~| expected a vtable
182 // bad trait object
183 const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
184 //~^ ERROR it is undefined behavior to use this value
185 //~| expected a vtable
186 const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
187 //~^ ERROR it is undefined behavior to use this value
188 //~| expected a vtable
189 // bad data *inside* the trait object
190 const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
191 //~^ ERROR it is undefined behavior to use this value
192 //~| expected a boolean
193
194 const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
195 //~^ ERROR it is undefined behavior to use this value
196 const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
197 //~^ ERROR it is undefined behavior to use this value
198
199
200 // not ok, since alignment needs to be non-zero.
201 const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
202 //~^ ERROR it is undefined behavior to use this value
203
204 // not ok, since alignment needs to be a power of two.
205 const LAYOUT_INVALID_THREE: Layout = unsafe { Layout::from_size_align_unchecked(9, 3) };
206 //~^ ERROR it is undefined behavior to use this value
207
208
209 const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior
210 const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior
211 const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; //~ ERROR undefined behavior
212
213
214 // Reading uninitialized  data
215 pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
216 //~^ ERROR: it is undefined behavior to use this value
217 // Reinterpret pointers as integers (UB in CTFE.)
218 pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) };
219 //~^ ERROR: it is undefined behavior to use this value
220 // Layout mismatch
221 pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
222 //~^ ERROR: it is undefined behavior to use this value
223
224 // Reading padding is not ok
225 pub static S7: &[u16] = unsafe {
226     //~^ ERROR: it is undefined behavior to use this value
227     let ptr = (&D2 as *const Struct as *const u16).add(1);
228
229     from_raw_parts(ptr, 4)
230 };
231
232 pub static R4: &[u8] = unsafe {
233     //~^ ERROR: it is undefined behavior to use this value
234     let ptr = (&D1) as *const mem::MaybeUninit<&u32> as *const u8;
235     from_ptr_range(ptr..ptr.add(1))
236 };
237 pub static R5: &[u8] = unsafe {
238     //~^ ERROR: it is undefined behavior to use this value
239     let ptr = &D3 as *const &u32;
240     from_ptr_range(ptr.cast()..ptr.add(1).cast())
241 };
242 pub static R6: &[bool] = unsafe {
243     //~^ ERROR: it is undefined behavior to use this value
244     let ptr = &D0 as *const u32 as *const bool;
245     from_ptr_range(ptr..ptr.add(4))
246 };
247
248 const D0: u32 = 0x11111111; // Constant chosen for endianness-independent behavior.
249 const D1: mem::MaybeUninit<&u32> = mem::MaybeUninit::uninit();
250 const D2: Struct = Struct { a: 1, b: 2, c: 3, d: 4 };
251 const D3: &u32 = &42;
252
253 #[repr(C)]
254 struct Struct {
255     a: u8,
256     // _pad: [mem::MaybeUninit<u8>; 3]
257     b: u32,
258     c: u16,
259     d: u8,
260     // _pad: [mem::MaybeUninit<u8>; 1]
261 }
262
263 fn main() {}