]> git.lizzy.rs Git - rust.git/blob - src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
Rollup merge of #93112 - pietroalbini:pa-cve-2022-21658-nightly, r=pietroalbini
[rust.git] / src / test / ui / intrinsics / panic-uninitialized-zeroed.rs
1 // run-pass
2 // needs-unwind
3 // ignore-wasm32-bare compiled with panic=abort by default
4 // revisions: mir thir
5 // [thir]compile-flags: -Zthir-unsafeck
6 // ignore-tidy-linelength
7
8 // This test checks panic emitted from `mem::{uninitialized,zeroed}`.
9
10 #![feature(never_type, arbitrary_enum_discriminant)]
11 #![allow(deprecated, invalid_value)]
12
13 use std::{
14     mem::{self, MaybeUninit, ManuallyDrop},
15     panic,
16     ptr::NonNull,
17     num,
18 };
19
20 #[allow(dead_code)]
21 struct Foo {
22     x: u8,
23     y: !,
24 }
25
26 enum Bar {}
27
28 #[allow(dead_code)]
29 enum OneVariant { Variant(i32) }
30
31 #[allow(dead_code, non_camel_case_types)]
32 enum OneVariant_NonZero {
33     Variant(i32, i32, num::NonZeroI32),
34     DeadVariant(Bar),
35 }
36
37 // An `Aggregate` abi enum where 0 is not a valid discriminant.
38 #[allow(dead_code)]
39 #[repr(i32)]
40 enum NoNullVariant {
41     Variant1(i32, i32) = 1,
42     Variant2(i32, i32) = 2,
43 }
44
45 // An enum with ScalarPair layout
46 #[allow(dead_code)]
47 enum LR {
48     Left(i64),
49     Right(i64),
50 }
51 #[allow(dead_code, non_camel_case_types)]
52 enum LR_NonZero {
53     Left(num::NonZeroI64),
54     Right(num::NonZeroI64),
55 }
56
57 fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
58     let err = panic::catch_unwind(op).err();
59     assert_eq!(
60         err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
61         Some(&msg)
62     );
63 }
64
65 fn main() {
66     unsafe {
67         // Uninhabited types
68         test_panic_msg(
69             || mem::uninitialized::<!>(),
70             "attempted to instantiate uninhabited type `!`"
71         );
72         test_panic_msg(
73             || mem::zeroed::<!>(),
74             "attempted to instantiate uninhabited type `!`"
75         );
76         test_panic_msg(
77             || MaybeUninit::<!>::uninit().assume_init(),
78             "attempted to instantiate uninhabited type `!`"
79         );
80
81         test_panic_msg(
82             || mem::uninitialized::<Foo>(),
83             "attempted to instantiate uninhabited type `Foo`"
84         );
85         test_panic_msg(
86             || mem::zeroed::<Foo>(),
87             "attempted to instantiate uninhabited type `Foo`"
88         );
89         test_panic_msg(
90             || MaybeUninit::<Foo>::uninit().assume_init(),
91             "attempted to instantiate uninhabited type `Foo`"
92         );
93
94         test_panic_msg(
95             || mem::uninitialized::<Bar>(),
96             "attempted to instantiate uninhabited type `Bar`"
97         );
98         test_panic_msg(
99             || mem::zeroed::<Bar>(),
100             "attempted to instantiate uninhabited type `Bar`"
101         );
102         test_panic_msg(
103             || MaybeUninit::<Bar>::uninit().assume_init(),
104             "attempted to instantiate uninhabited type `Bar`"
105         );
106
107         // Types that do not like zero-initialziation
108         test_panic_msg(
109             || mem::uninitialized::<fn()>(),
110             "attempted to leave type `fn()` uninitialized, which is invalid"
111         );
112         test_panic_msg(
113             || mem::zeroed::<fn()>(),
114             "attempted to zero-initialize type `fn()`, which is invalid"
115         );
116
117         test_panic_msg(
118             || mem::uninitialized::<*const dyn Send>(),
119             "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
120         );
121         test_panic_msg(
122             || mem::zeroed::<*const dyn Send>(),
123             "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
124         );
125
126         /* FIXME(#66151) we conservatively do not error here yet.
127         test_panic_msg(
128             || mem::uninitialized::<LR_NonZero>(),
129             "attempted to leave type `LR_NonZero` uninitialized, which is invalid"
130         );
131         test_panic_msg(
132             || mem::zeroed::<LR_NonZero>(),
133             "attempted to zero-initialize type `LR_NonZero`, which is invalid"
134         );
135
136         test_panic_msg(
137             || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
138             "attempted to leave type `std::mem::ManuallyDrop<LR_NonZero>` uninitialized, \
139              which is invalid"
140         );
141         test_panic_msg(
142             || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
143             "attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
144              which is invalid"
145         );
146         */
147
148         test_panic_msg(
149             || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
150             "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
151                 which is invalid"
152         );
153         test_panic_msg(
154             || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
155             "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
156                 which is invalid"
157         );
158
159         test_panic_msg(
160             || mem::uninitialized::<OneVariant_NonZero>(),
161             "attempted to leave type `OneVariant_NonZero` uninitialized, \
162                 which is invalid"
163         );
164         test_panic_msg(
165             || mem::zeroed::<OneVariant_NonZero>(),
166             "attempted to zero-initialize type `OneVariant_NonZero`, \
167                 which is invalid"
168         );
169
170         test_panic_msg(
171             || mem::uninitialized::<NoNullVariant>(),
172             "attempted to leave type `NoNullVariant` uninitialized, \
173                 which is invalid"
174         );
175         test_panic_msg(
176             || mem::zeroed::<NoNullVariant>(),
177             "attempted to zero-initialize type `NoNullVariant`, \
178                 which is invalid"
179         );
180
181         // Types that can be zero, but not uninit.
182         test_panic_msg(
183             || mem::uninitialized::<bool>(),
184             "attempted to leave type `bool` uninitialized, which is invalid"
185         );
186         test_panic_msg(
187             || mem::uninitialized::<LR>(),
188             "attempted to leave type `LR` uninitialized, which is invalid"
189         );
190         test_panic_msg(
191             || mem::uninitialized::<ManuallyDrop<LR>>(),
192             "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
193         );
194
195         // Some things that should work.
196         let _val = mem::zeroed::<bool>();
197         let _val = mem::zeroed::<LR>();
198         let _val = mem::zeroed::<ManuallyDrop<LR>>();
199         let _val = mem::zeroed::<OneVariant>();
200         let _val = mem::zeroed::<Option<&'static i32>>();
201         let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
202         let _val = mem::uninitialized::<MaybeUninit<bool>>();
203
204         // These are UB because they have not been officially blessed, but we await the resolution
205         // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
206         // anything about that.
207         let _val = mem::uninitialized::<i32>();
208         let _val = mem::uninitialized::<*const ()>();
209     }
210 }