Skip to content

Commit 2825e53

Browse files
committed
might_permit_raw_init: also check arrays
1 parent 20328b5 commit 2825e53

File tree

2 files changed

+108
-3
lines changed

2 files changed

+108
-3
lines changed

compiler/rustc_target/src/abi/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,8 +1162,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> {
11621162
// If we have not found an error yet, we need to recursively descend into fields.
11631163
match &self.fields {
11641164
FieldsShape::Primitive | FieldsShape::Union { .. } => {}
1165-
FieldsShape::Array { .. } => {
1166-
// FIXME(#66151): For now, we are conservative and do not check arrays.
1165+
FieldsShape::Array { count, .. } => {
1166+
if !(*count == 0
1167+
|| self.field(cx, 0).to_result()?.might_permit_raw_init(cx, zero)?)
1168+
{
1169+
// Found non empty array with a type that is unhappy about this kind of initialization
1170+
return Ok(false);
1171+
}
11671172
}
11681173
FieldsShape::Arbitrary { offsets, .. } => {
11691174
for idx in 0..offsets.len() {

src/test/ui/intrinsics/panic-uninitialized-zeroed.rs

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,59 +65,111 @@ fn main() {
6565
|| mem::uninitialized::<!>(),
6666
"attempted to instantiate uninhabited type `!`"
6767
);
68+
test_panic_msg(
69+
|| mem::uninitialized::<[!; 2]>(),
70+
"attempted to instantiate uninhabited type `[!; 2]`"
71+
);
6872
test_panic_msg(
6973
|| mem::zeroed::<!>(),
7074
"attempted to instantiate uninhabited type `!`"
7175
);
76+
test_panic_msg(
77+
|| mem::zeroed::<[!; 2]>(),
78+
"attempted to instantiate uninhabited type `[!; 2]`"
79+
);
7280
test_panic_msg(
7381
|| MaybeUninit::<!>::uninit().assume_init(),
7482
"attempted to instantiate uninhabited type `!`"
7583
);
84+
test_panic_msg(
85+
|| MaybeUninit::<[!; 2]>::uninit().assume_init(),
86+
"attempted to instantiate uninhabited type `[!; 2]`"
87+
);
7688

7789
test_panic_msg(
7890
|| mem::uninitialized::<Foo>(),
7991
"attempted to instantiate uninhabited type `Foo`"
8092
);
93+
test_panic_msg(
94+
|| mem::uninitialized::<[Foo; 2]>(),
95+
"attempted to instantiate uninhabited type `[Foo; 2]`"
96+
);
8197
test_panic_msg(
8298
|| mem::zeroed::<Foo>(),
8399
"attempted to instantiate uninhabited type `Foo`"
84100
);
101+
test_panic_msg(
102+
|| mem::zeroed::<[Foo; 2]>(),
103+
"attempted to instantiate uninhabited type `[Foo; 2]`"
104+
);
85105
test_panic_msg(
86106
|| MaybeUninit::<Foo>::uninit().assume_init(),
87107
"attempted to instantiate uninhabited type `Foo`"
88108
);
109+
test_panic_msg(
110+
|| MaybeUninit::<[Foo; 2]>::uninit().assume_init(),
111+
"attempted to instantiate uninhabited type `[Foo; 2]`"
112+
);
89113

90114
test_panic_msg(
91115
|| mem::uninitialized::<Bar>(),
92116
"attempted to instantiate uninhabited type `Bar`"
93117
);
118+
test_panic_msg(
119+
|| mem::uninitialized::<[Bar; 4]>(),
120+
"attempted to instantiate uninhabited type `[Bar; 4]`"
121+
);
94122
test_panic_msg(
95123
|| mem::zeroed::<Bar>(),
96124
"attempted to instantiate uninhabited type `Bar`"
97125
);
126+
test_panic_msg(
127+
|| mem::zeroed::<[Bar; 4]>(),
128+
"attempted to instantiate uninhabited type `[Bar; 4]`"
129+
);
98130
test_panic_msg(
99131
|| MaybeUninit::<Bar>::uninit().assume_init(),
100132
"attempted to instantiate uninhabited type `Bar`"
101133
);
134+
test_panic_msg(
135+
|| MaybeUninit::<[Bar; 4]>::uninit().assume_init(),
136+
"attempted to instantiate uninhabited type `[Bar; 4]`"
137+
);
102138

103-
// Types that do not like zero-initialziation
139+
// Types that do not like zero-initialization
104140
test_panic_msg(
105141
|| mem::uninitialized::<fn()>(),
106142
"attempted to leave type `fn()` uninitialized, which is invalid"
107143
);
144+
test_panic_msg(
145+
|| mem::uninitialized::<[fn(); 2]>(),
146+
"attempted to leave type `[fn(); 2]` uninitialized, which is invalid"
147+
);
108148
test_panic_msg(
109149
|| mem::zeroed::<fn()>(),
110150
"attempted to zero-initialize type `fn()`, which is invalid"
111151
);
152+
test_panic_msg(
153+
|| mem::zeroed::<[fn(); 2]>(),
154+
"attempted to zero-initialize type `[fn(); 2]`, which is invalid"
155+
);
112156

113157
test_panic_msg(
114158
|| mem::uninitialized::<*const dyn Send>(),
115159
"attempted to leave type `*const dyn std::marker::Send` uninitialized, which is invalid"
116160
);
161+
test_panic_msg(
162+
|| mem::uninitialized::<[*const dyn Send; 2]>(),
163+
"attempted to leave type `[*const dyn std::marker::Send; 2]` uninitialized, which is invalid"
164+
);
117165
test_panic_msg(
118166
|| mem::zeroed::<*const dyn Send>(),
119167
"attempted to zero-initialize type `*const dyn std::marker::Send`, which is invalid"
120168
);
169+
test_panic_msg(
170+
|| mem::zeroed::<[*const dyn Send; 2]>(),
171+
"attempted to zero-initialize type `[*const dyn std::marker::Send; 2]`, which is invalid"
172+
);
121173

122174
/* FIXME(#66151) we conservatively do not error here yet.
123175
test_panic_msg(
@@ -146,39 +198,73 @@ fn main() {
146198
"attempted to leave type `(std::ptr::NonNull<u32>, u32, u32)` uninitialized, \
147199
which is invalid"
148200
);
201+
test_panic_msg(
202+
|| mem::uninitialized::<[(NonNull<u32>, u32, u32); 2]>(),
203+
"attempted to leave type `[(std::ptr::NonNull<u32>, u32, u32); 2]` uninitialized, \
204+
which is invalid"
205+
);
149206
test_panic_msg(
150207
|| mem::zeroed::<(NonNull<u32>, u32, u32)>(),
151208
"attempted to zero-initialize type `(std::ptr::NonNull<u32>, u32, u32)`, \
152209
which is invalid"
153210
);
211+
test_panic_msg(
212+
|| mem::zeroed::<[(NonNull<u32>, u32, u32); 2]>(),
213+
"attempted to zero-initialize type `[(std::ptr::NonNull<u32>, u32, u32); 2]`, \
214+
which is invalid"
215+
);
154216

155217
test_panic_msg(
156218
|| mem::uninitialized::<OneVariant_NonZero>(),
157219
"attempted to leave type `OneVariant_NonZero` uninitialized, \
158220
which is invalid"
159221
);
222+
test_panic_msg(
223+
|| mem::uninitialized::<[OneVariant_NonZero; 2]>(),
224+
"attempted to leave type `[OneVariant_NonZero; 2]` uninitialized, \
225+
which is invalid"
226+
);
160227
test_panic_msg(
161228
|| mem::zeroed::<OneVariant_NonZero>(),
162229
"attempted to zero-initialize type `OneVariant_NonZero`, \
163230
which is invalid"
164231
);
232+
test_panic_msg(
233+
|| mem::zeroed::<[OneVariant_NonZero; 2]>(),
234+
"attempted to zero-initialize type `[OneVariant_NonZero; 2]`, \
235+
which is invalid"
236+
);
165237

166238
test_panic_msg(
167239
|| mem::uninitialized::<NoNullVariant>(),
168240
"attempted to leave type `NoNullVariant` uninitialized, \
169241
which is invalid"
170242
);
243+
test_panic_msg(
244+
|| mem::uninitialized::<[NoNullVariant; 2]>(),
245+
"attempted to leave type `[NoNullVariant; 2]` uninitialized, \
246+
which is invalid"
247+
);
171248
test_panic_msg(
172249
|| mem::zeroed::<NoNullVariant>(),
173250
"attempted to zero-initialize type `NoNullVariant`, \
174251
which is invalid"
175252
);
253+
test_panic_msg(
254+
|| mem::zeroed::<[NoNullVariant; 2]>(),
255+
"attempted to zero-initialize type `[NoNullVariant; 2]`, \
256+
which is invalid"
257+
);
176258

177259
// Types that can be zero, but not uninit.
178260
test_panic_msg(
179261
|| mem::uninitialized::<bool>(),
180262
"attempted to leave type `bool` uninitialized, which is invalid"
181263
);
264+
test_panic_msg(
265+
|| mem::uninitialized::<[bool; 2]>(),
266+
"attempted to leave type `[bool; 2]` uninitialized, which is invalid"
267+
);
182268
test_panic_msg(
183269
|| mem::uninitialized::<LR>(),
184270
"attempted to leave type `LR` uninitialized, which is invalid"
@@ -190,17 +276,31 @@ fn main() {
190276

191277
// Some things that should work.
192278
let _val = mem::zeroed::<bool>();
279+
let _val = mem::zeroed::<[bool; 4]>();
193280
let _val = mem::zeroed::<LR>();
281+
let _val = mem::zeroed::<[LR; 8]>();
194282
let _val = mem::zeroed::<ManuallyDrop<LR>>();
283+
let _val = mem::zeroed::<[ManuallyDrop<LR>; 16]>();
195284
let _val = mem::zeroed::<OneVariant>();
285+
let _val = mem::zeroed::<[OneVariant; 2]>();
196286
let _val = mem::zeroed::<Option<&'static i32>>();
287+
let _val = mem::zeroed::<[Option<&'static i32>; 3]>();
197288
let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
289+
let _val = mem::zeroed::<[MaybeUninit<NonNull<u32>>; 32]>();
290+
let _val = mem::zeroed::<[!; 0]>();
198291
let _val = mem::uninitialized::<MaybeUninit<bool>>();
292+
let _val = mem::uninitialized::<[MaybeUninit<bool>; 1]>();
293+
let _val = mem::uninitialized::<[bool; 0]>();
294+
let _val = mem::uninitialized::<[!; 0]>();
295+
let _val = mem::uninitialized::<[fn(); 0]>();
296+
let _val = mem::uninitialized::<[*const dyn Send; 0]>();
199297

200298
// These are UB because they have not been officially blessed, but we await the resolution
201299
// of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
202300
// anything about that.
203301
let _val = mem::uninitialized::<i32>();
302+
let _val = mem::uninitialized::<[i32; 1]>();
204303
let _val = mem::uninitialized::<*const ()>();
304+
let _val = mem::uninitialized::<[*const (); 2]>();
205305
}
206306
}

0 commit comments

Comments
 (0)