From 76e2f190922518c0d747c22de7f12cbae678fb57 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Nov 2020 09:52:11 -0300 Subject: [PATCH 1/4] 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 a57ad8f2bbd1b..95ed3c2bc2725 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1334,8 +1334,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 a1cfee944c8bd..95880e2e660dd 100644 --- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -69,59 +69,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 core::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 core::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( @@ -150,39 +202,73 @@ fn main() { "attempted to leave type `(core::ptr::non_null::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 `(core::ptr::non_null::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" @@ -194,17 +280,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 0cae7be258b314a117cc41f26bd7434112e425a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Nov 2020 10:49:47 -0300 Subject: [PATCH 2/4] 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 95ed3c2bc2725..53130af3a0160 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1335,9 +1335,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 90f1c7f30c902d0805932e631a9b14f922f390af Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Nov 2020 10:50:20 -0300 Subject: [PATCH 3/4] Reorder tests in panic-uninit-zeroed --- .../intrinsics/panic-uninitialized-zeroed.rs | 93 +++++++++++-------- 1 file changed, 52 insertions(+), 41 deletions(-) diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs index 95880e2e660dd..bc9b66ad7b698 100644 --- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -70,20 +70,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(), @@ -95,20 +95,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(), @@ -120,20 +120,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(), @@ -145,14 +145,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" @@ -162,17 +162,19 @@ fn main() { || mem::uninitialized::<*const dyn Send>(), "attempted to leave type `*const dyn core::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 core::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. @@ -203,8 +205,8 @@ 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( @@ -224,13 +226,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( @@ -245,13 +247,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( @@ -265,10 +267,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" @@ -277,6 +275,19 @@ fn main() { || mem::uninitialized::>(), "attempted to leave type `core::mem::manually_drop::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::(); From 87216f4e9ea1a48d68465aee40612e583f0445a1 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Tue, 14 Dec 2021 16:09:12 -0500 Subject: [PATCH 4/4] Fix compilation errors --- compiler/rustc_target/src/abi/mod.rs | 4 ++-- src/test/ui/intrinsics/panic-uninitialized-zeroed.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 53130af3a0160..c5097e877d5bc 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1335,9 +1335,9 @@ 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).might_permit_raw_init(cx, zero) { // Found non empty array with a type that is unhappy about this kind of initialization - return Ok(false); + return false; } } FieldsShape::Arbitrary { offsets, .. } => { diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs index bc9b66ad7b698..ba114f8a319c6 100644 --- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs +++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs @@ -168,12 +168,12 @@ fn main() { ); test_panic_msg( || mem::uninitialized::<[*const dyn Send; 2]>(), - "attempted to leave type `[*const dyn std::marker::Send; 2]` uninitialized, \ + "attempted to leave type `[*const dyn core::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]`, \ + "attempted to zero-initialize type `[*const dyn core::marker::Send; 2]`, \ which is invalid" ); @@ -206,7 +206,7 @@ fn main() { ); test_panic_msg( || mem::zeroed::<(NonNull, u32, u32)>(), - "attempted to zero-initialize type `(std::ptr::NonNull, u32, u32)`, \ + "attempted to zero-initialize type `(core::ptr::non_null::NonNull, u32, u32)`, \ which is invalid" ); test_panic_msg( @@ -216,7 +216,7 @@ fn main() { ); test_panic_msg( || mem::zeroed::<[(NonNull, u32, u32); 2]>(), - "attempted to zero-initialize type `[(std::ptr::NonNull, u32, u32); 2]`, \ + "attempted to zero-initialize type `[(core::ptr::non_null::NonNull, u32, u32); 2]`, \ which is invalid" ); @@ -285,7 +285,7 @@ fn main() { ); test_panic_msg( || mem::uninitialized::<[ManuallyDrop; 2]>(), - "attempted to leave type `[std::mem::ManuallyDrop; 2]` uninitialized, \ + "attempted to leave type `[core::mem::manually_drop::ManuallyDrop; 2]` uninitialized, \ which is invalid" );