From 2825e5399f4b1c81065be17cbe92c990ad2730a3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Nov 2020 09:52:11 -0300 Subject: [PATCH 1/3] might_permit_raw_init: also check arrays --- compiler/rustc_target/src/abi/mod.rs | 9 +- .../intrinsics/panic-uninitialized-zeroed.rs | 102 +++++++++++++++++- 2 files changed, 108 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index a43080b09e9a1..db71b495aecbc 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1162,8 +1162,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { // If we have not found an error yet, we need to recursively descend into fields. match &self.fields { FieldsShape::Primitive | FieldsShape::Union { .. } => {} - FieldsShape::Array { .. } => { - // FIXME(#66151): For now, we are conservative and do not check arrays. + FieldsShape::Array { count, .. } => { + if !(*count == 0 + || self.field(cx, 0).to_result()?.might_permit_raw_init(cx, zero)?) + { + // Found non empty array with a type that is unhappy about this kind of initialization + return Ok(false); + } } FieldsShape::Arbitrary { offsets, .. } => { for idx in 0..offsets.len() { diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs index 4a91198ab9f6f..0c2994111462c 100644 --- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -65,59 +65,111 @@ fn main() { || mem::uninitialized::(), "attempted to instantiate uninhabited type `!`" ); + test_panic_msg( + || mem::uninitialized::<[!; 2]>(), + "attempted to instantiate uninhabited type `[!; 2]`" + ); test_panic_msg( || mem::zeroed::(), "attempted to instantiate uninhabited type `!`" ); + test_panic_msg( + || mem::zeroed::<[!; 2]>(), + "attempted to instantiate uninhabited type `[!; 2]`" + ); test_panic_msg( || MaybeUninit::::uninit().assume_init(), "attempted to instantiate uninhabited type `!`" ); + test_panic_msg( + || MaybeUninit::<[!; 2]>::uninit().assume_init(), + "attempted to instantiate uninhabited type `[!; 2]`" + ); test_panic_msg( || mem::uninitialized::(), "attempted to instantiate uninhabited type `Foo`" ); + test_panic_msg( + || mem::uninitialized::<[Foo; 2]>(), + "attempted to instantiate uninhabited type `[Foo; 2]`" + ); test_panic_msg( || mem::zeroed::(), "attempted to instantiate uninhabited type `Foo`" ); + test_panic_msg( + || mem::zeroed::<[Foo; 2]>(), + "attempted to instantiate uninhabited type `[Foo; 2]`" + ); test_panic_msg( || MaybeUninit::::uninit().assume_init(), "attempted to instantiate uninhabited type `Foo`" ); + test_panic_msg( + || MaybeUninit::<[Foo; 2]>::uninit().assume_init(), + "attempted to instantiate uninhabited type `[Foo; 2]`" + ); test_panic_msg( || mem::uninitialized::(), "attempted to instantiate uninhabited type `Bar`" ); + test_panic_msg( + || mem::uninitialized::<[Bar; 4]>(), + "attempted to instantiate uninhabited type `[Bar; 4]`" + ); test_panic_msg( || mem::zeroed::(), "attempted to instantiate uninhabited type `Bar`" ); + test_panic_msg( + || mem::zeroed::<[Bar; 4]>(), + "attempted to instantiate uninhabited type `[Bar; 4]`" + ); test_panic_msg( || MaybeUninit::::uninit().assume_init(), "attempted to instantiate uninhabited type `Bar`" ); + test_panic_msg( + || MaybeUninit::<[Bar; 4]>::uninit().assume_init(), + "attempted to instantiate uninhabited type `[Bar; 4]`" + ); - // Types that do not like zero-initialziation + // Types that do not like zero-initialization test_panic_msg( || mem::uninitialized::(), "attempted to leave type `fn()` uninitialized, which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[fn(); 2]>(), + "attempted to leave type `[fn(); 2]` uninitialized, which is invalid" + ); test_panic_msg( || mem::zeroed::(), "attempted to zero-initialize type `fn()`, which is invalid" ); + test_panic_msg( + || mem::zeroed::<[fn(); 2]>(), + "attempted to zero-initialize type `[fn(); 2]`, which is invalid" + ); test_panic_msg( || mem::uninitialized::<*const dyn Send>(), "attempted to leave type `*const dyn std::marker::Send` uninitialized, which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[*const dyn Send; 2]>(), + "attempted to leave type `[*const dyn std::marker::Send; 2]` uninitialized, which is invalid" + ); test_panic_msg( || mem::zeroed::<*const dyn Send>(), "attempted to zero-initialize type `*const dyn std::marker::Send`, which is invalid" ); + test_panic_msg( + || mem::zeroed::<[*const dyn Send; 2]>(), + "attempted to zero-initialize type `[*const dyn std::marker::Send; 2]`, which is invalid" + ); /* FIXME(#66151) we conservatively do not error here yet. test_panic_msg( @@ -146,39 +198,73 @@ fn main() { "attempted to leave type `(std::ptr::NonNull, u32, u32)` uninitialized, \ which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[(NonNull, u32, u32); 2]>(), + "attempted to leave type `[(std::ptr::NonNull, u32, u32); 2]` uninitialized, \ + which is invalid" + ); test_panic_msg( || mem::zeroed::<(NonNull, u32, u32)>(), "attempted to zero-initialize type `(std::ptr::NonNull, u32, u32)`, \ which is invalid" ); + test_panic_msg( + || mem::zeroed::<[(NonNull, u32, u32); 2]>(), + "attempted to zero-initialize type `[(std::ptr::NonNull, u32, u32); 2]`, \ + which is invalid" + ); test_panic_msg( || mem::uninitialized::(), "attempted to leave type `OneVariant_NonZero` uninitialized, \ which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[OneVariant_NonZero; 2]>(), + "attempted to leave type `[OneVariant_NonZero; 2]` uninitialized, \ + which is invalid" + ); test_panic_msg( || mem::zeroed::(), "attempted to zero-initialize type `OneVariant_NonZero`, \ which is invalid" ); + test_panic_msg( + || mem::zeroed::<[OneVariant_NonZero; 2]>(), + "attempted to zero-initialize type `[OneVariant_NonZero; 2]`, \ + which is invalid" + ); test_panic_msg( || mem::uninitialized::(), "attempted to leave type `NoNullVariant` uninitialized, \ which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[NoNullVariant; 2]>(), + "attempted to leave type `[NoNullVariant; 2]` uninitialized, \ + which is invalid" + ); test_panic_msg( || mem::zeroed::(), "attempted to zero-initialize type `NoNullVariant`, \ which is invalid" ); + test_panic_msg( + || mem::zeroed::<[NoNullVariant; 2]>(), + "attempted to zero-initialize type `[NoNullVariant; 2]`, \ + which is invalid" + ); // Types that can be zero, but not uninit. test_panic_msg( || mem::uninitialized::(), "attempted to leave type `bool` uninitialized, which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[bool; 2]>(), + "attempted to leave type `[bool; 2]` uninitialized, which is invalid" + ); test_panic_msg( || mem::uninitialized::(), "attempted to leave type `LR` uninitialized, which is invalid" @@ -190,17 +276,31 @@ fn main() { // Some things that should work. let _val = mem::zeroed::(); + let _val = mem::zeroed::<[bool; 4]>(); let _val = mem::zeroed::(); + let _val = mem::zeroed::<[LR; 8]>(); let _val = mem::zeroed::>(); + let _val = mem::zeroed::<[ManuallyDrop; 16]>(); let _val = mem::zeroed::(); + let _val = mem::zeroed::<[OneVariant; 2]>(); let _val = mem::zeroed::>(); + let _val = mem::zeroed::<[Option<&'static i32>; 3]>(); let _val = mem::zeroed::>>(); + let _val = mem::zeroed::<[MaybeUninit>; 32]>(); + let _val = mem::zeroed::<[!; 0]>(); let _val = mem::uninitialized::>(); + let _val = mem::uninitialized::<[MaybeUninit; 1]>(); + let _val = mem::uninitialized::<[bool; 0]>(); + let _val = mem::uninitialized::<[!; 0]>(); + let _val = mem::uninitialized::<[fn(); 0]>(); + let _val = mem::uninitialized::<[*const dyn Send; 0]>(); // These are UB because they have not been officially blessed, but we await the resolution // of before doing // anything about that. let _val = mem::uninitialized::(); + let _val = mem::uninitialized::<[i32; 1]>(); let _val = mem::uninitialized::<*const ()>(); + let _val = mem::uninitialized::<[*const (); 2]>(); } } From 2af912199a48a879ca1ae1e1cd41a1616b647eb8 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Nov 2020 10:49:47 -0300 Subject: [PATCH 2/3] More readable condition --- compiler/rustc_target/src/abi/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index db71b495aecbc..83f8c3dc138a6 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1163,9 +1163,7 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { match &self.fields { FieldsShape::Primitive | FieldsShape::Union { .. } => {} FieldsShape::Array { count, .. } => { - if !(*count == 0 - || self.field(cx, 0).to_result()?.might_permit_raw_init(cx, zero)?) - { + if *count > 0 && !self.field(cx, 0).to_result()?.might_permit_raw_init(cx, zero)? { // Found non empty array with a type that is unhappy about this kind of initialization return Ok(false); } From a6f7780f75ee83e5ac2ff51446a57edbf555d835 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Nov 2020 10:50:20 -0300 Subject: [PATCH 3/3] Reorder tests in panic-uninit-zeroed --- .../intrinsics/panic-uninitialized-zeroed.rs | 97 +++++++++++-------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs index 0c2994111462c..4cf4df73a14e7 100644 --- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -66,20 +66,20 @@ fn main() { "attempted to instantiate uninhabited type `!`" ); test_panic_msg( - || mem::uninitialized::<[!; 2]>(), - "attempted to instantiate uninhabited type `[!; 2]`" + || mem::zeroed::(), + "attempted to instantiate uninhabited type `!`" ); test_panic_msg( - || mem::zeroed::(), + || MaybeUninit::::uninit().assume_init(), "attempted to instantiate uninhabited type `!`" ); test_panic_msg( - || mem::zeroed::<[!; 2]>(), + || mem::uninitialized::<[!; 2]>(), "attempted to instantiate uninhabited type `[!; 2]`" ); test_panic_msg( - || MaybeUninit::::uninit().assume_init(), - "attempted to instantiate uninhabited type `!`" + || mem::zeroed::<[!; 2]>(), + "attempted to instantiate uninhabited type `[!; 2]`" ); test_panic_msg( || MaybeUninit::<[!; 2]>::uninit().assume_init(), @@ -91,20 +91,20 @@ fn main() { "attempted to instantiate uninhabited type `Foo`" ); test_panic_msg( - || mem::uninitialized::<[Foo; 2]>(), - "attempted to instantiate uninhabited type `[Foo; 2]`" + || mem::zeroed::(), + "attempted to instantiate uninhabited type `Foo`" ); test_panic_msg( - || mem::zeroed::(), + || MaybeUninit::::uninit().assume_init(), "attempted to instantiate uninhabited type `Foo`" ); test_panic_msg( - || mem::zeroed::<[Foo; 2]>(), + || mem::uninitialized::<[Foo; 2]>(), "attempted to instantiate uninhabited type `[Foo; 2]`" ); test_panic_msg( - || MaybeUninit::::uninit().assume_init(), - "attempted to instantiate uninhabited type `Foo`" + || mem::zeroed::<[Foo; 2]>(), + "attempted to instantiate uninhabited type `[Foo; 2]`" ); test_panic_msg( || MaybeUninit::<[Foo; 2]>::uninit().assume_init(), @@ -116,20 +116,20 @@ fn main() { "attempted to instantiate uninhabited type `Bar`" ); test_panic_msg( - || mem::uninitialized::<[Bar; 4]>(), - "attempted to instantiate uninhabited type `[Bar; 4]`" + || mem::zeroed::(), + "attempted to instantiate uninhabited type `Bar`" ); test_panic_msg( - || mem::zeroed::(), + || MaybeUninit::::uninit().assume_init(), "attempted to instantiate uninhabited type `Bar`" ); test_panic_msg( - || mem::zeroed::<[Bar; 4]>(), + || mem::uninitialized::<[Bar; 4]>(), "attempted to instantiate uninhabited type `[Bar; 4]`" ); test_panic_msg( - || MaybeUninit::::uninit().assume_init(), - "attempted to instantiate uninhabited type `Bar`" + || mem::zeroed::<[Bar; 4]>(), + "attempted to instantiate uninhabited type `[Bar; 4]`" ); test_panic_msg( || MaybeUninit::<[Bar; 4]>::uninit().assume_init(), @@ -141,14 +141,14 @@ fn main() { || mem::uninitialized::(), "attempted to leave type `fn()` uninitialized, which is invalid" ); - test_panic_msg( - || mem::uninitialized::<[fn(); 2]>(), - "attempted to leave type `[fn(); 2]` uninitialized, which is invalid" - ); test_panic_msg( || mem::zeroed::(), "attempted to zero-initialize type `fn()`, which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[fn(); 2]>(), + "attempted to leave type `[fn(); 2]` uninitialized, which is invalid" + ); test_panic_msg( || mem::zeroed::<[fn(); 2]>(), "attempted to zero-initialize type `[fn(); 2]`, which is invalid" @@ -158,17 +158,19 @@ fn main() { || mem::uninitialized::<*const dyn Send>(), "attempted to leave type `*const dyn std::marker::Send` uninitialized, which is invalid" ); - test_panic_msg( - || mem::uninitialized::<[*const dyn Send; 2]>(), - "attempted to leave type `[*const dyn std::marker::Send; 2]` uninitialized, which is invalid" - ); test_panic_msg( || mem::zeroed::<*const dyn Send>(), "attempted to zero-initialize type `*const dyn std::marker::Send`, which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[*const dyn Send; 2]>(), + "attempted to leave type `[*const dyn std::marker::Send; 2]` uninitialized, \ + which is invalid" + ); test_panic_msg( || mem::zeroed::<[*const dyn Send; 2]>(), - "attempted to zero-initialize type `[*const dyn std::marker::Send; 2]`, which is invalid" + "attempted to zero-initialize type `[*const dyn std::marker::Send; 2]`, \ + which is invalid" ); /* FIXME(#66151) we conservatively do not error here yet. @@ -199,13 +201,13 @@ fn main() { which is invalid" ); test_panic_msg( - || mem::uninitialized::<[(NonNull, u32, u32); 2]>(), - "attempted to leave type `[(std::ptr::NonNull, u32, u32); 2]` uninitialized, \ + || mem::zeroed::<(NonNull, u32, u32)>(), + "attempted to zero-initialize type `(std::ptr::NonNull, u32, u32)`, \ which is invalid" ); test_panic_msg( - || mem::zeroed::<(NonNull, u32, u32)>(), - "attempted to zero-initialize type `(std::ptr::NonNull, u32, u32)`, \ + || mem::uninitialized::<[(NonNull, u32, u32); 2]>(), + "attempted to leave type `[(std::ptr::NonNull, u32, u32); 2]` uninitialized, \ which is invalid" ); test_panic_msg( @@ -220,13 +222,13 @@ fn main() { which is invalid" ); test_panic_msg( - || mem::uninitialized::<[OneVariant_NonZero; 2]>(), - "attempted to leave type `[OneVariant_NonZero; 2]` uninitialized, \ + || mem::zeroed::(), + "attempted to zero-initialize type `OneVariant_NonZero`, \ which is invalid" ); test_panic_msg( - || mem::zeroed::(), - "attempted to zero-initialize type `OneVariant_NonZero`, \ + || mem::uninitialized::<[OneVariant_NonZero; 2]>(), + "attempted to leave type `[OneVariant_NonZero; 2]` uninitialized, \ which is invalid" ); test_panic_msg( @@ -241,13 +243,13 @@ fn main() { which is invalid" ); test_panic_msg( - || mem::uninitialized::<[NoNullVariant; 2]>(), - "attempted to leave type `[NoNullVariant; 2]` uninitialized, \ + || mem::zeroed::(), + "attempted to zero-initialize type `NoNullVariant`, \ which is invalid" ); test_panic_msg( - || mem::zeroed::(), - "attempted to zero-initialize type `NoNullVariant`, \ + || mem::uninitialized::<[NoNullVariant; 2]>(), + "attempted to leave type `[NoNullVariant; 2]` uninitialized, \ which is invalid" ); test_panic_msg( @@ -261,10 +263,6 @@ fn main() { || mem::uninitialized::(), "attempted to leave type `bool` uninitialized, which is invalid" ); - test_panic_msg( - || mem::uninitialized::<[bool; 2]>(), - "attempted to leave type `[bool; 2]` uninitialized, which is invalid" - ); test_panic_msg( || mem::uninitialized::(), "attempted to leave type `LR` uninitialized, which is invalid" @@ -273,6 +271,19 @@ fn main() { || mem::uninitialized::>(), "attempted to leave type `std::mem::ManuallyDrop` uninitialized, which is invalid" ); + test_panic_msg( + || mem::uninitialized::<[bool; 2]>(), + "attempted to leave type `[bool; 2]` uninitialized, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<[LR; 2]>(), + "attempted to leave type `[LR; 2]` uninitialized, which is invalid" + ); + test_panic_msg( + || mem::uninitialized::<[ManuallyDrop; 2]>(), + "attempted to leave type `[std::mem::ManuallyDrop; 2]` uninitialized, \ + which is invalid" + ); // Some things that should work. let _val = mem::zeroed::();