From 881e65c01bfa5e483aa7deed3aee9771d672f231 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 11 Mar 2020 14:58:27 +0200 Subject: [PATCH 1/4] bump rust-version to latest --- rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust-version b/rust-version index f8f856bff76..fb138448f9f 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -3dbade652ed8ebac70f903e01f51cd92c4e4302c +303d8aff6092709edd4dbd35b1c88e9aa40bf6d8 From e81ebffa59929574c8ac8fa380e27eb9e612cff9 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 11 Mar 2020 15:39:37 +0200 Subject: [PATCH 2/4] Implement panic_if_any_invalid and panic_if_zero_invalid intrinsics --- src/shims/intrinsics.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index 05047a6040c..d0305c0e9fb 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -449,7 +449,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let layout = this.layout_of(ty)?; if layout.abi.is_uninhabited() { // Return here because we paniced instead of returning normally from the intrinsic. - return this.start_panic(&format!("Attempted to instantiate uninhabited type {}", ty), unwind); + return this.start_panic(&format!("attempted to instantiate uninhabited type {}", ty), unwind); + } + } + + "panic_if_zero_invalid" => { + let ty = substs.type_at(0); + let layout = this.layout_of(ty)?; + // Check if it permits zeroed raw initialization + if !layout.might_permit_raw_init(this, /*zero:*/ true).unwrap() { + // Return here because we paniced instead of returning normally from the intrinsic. + return this.start_panic(&format!("attempted to zero-initialize type `{}`, which is invalid", ty), unwind); + } + } + + "panic_if_any_invalid" => { + let ty = substs.type_at(0); + let layout = this.layout_of(ty)?; + // rustc handles all these in a single function, but we don't so we need to make sure `mem::uninitialized::()` returns the right error. + // So we check for `is_uninhabited` here too. + if layout.abi.is_uninhabited() { + return this.start_panic(&format!("attempted to instantiate uninhabited type {}", ty), unwind); + } + // Check if it permits any raw initialization + if !layout.might_permit_raw_init(this, /*zero:*/ false).unwrap() { + // Return here because we paniced instead of returning normally from the intrinsic. + return this.start_panic(&format!("attempted to leave type `{}` uninitialized, which is invalid", ty), unwind); } } From 2802c3cf0b91e18de1f37e24929a406033df0cc0 Mon Sep 17 00:00:00 2001 From: Elichai Turkel Date: Wed, 11 Mar 2020 16:02:49 +0200 Subject: [PATCH 3/4] Add tests for the new panic_if_any_invalid, panic_if_zero_invalid intrinsics --- tests/run-pass/panic/catch_panic.rs | 39 ++++++++++++++++++++++--- tests/run-pass/panic/catch_panic.stderr | 22 +++++++++++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/tests/run-pass/panic/catch_panic.rs b/tests/run-pass/panic/catch_panic.rs index 33c2beb682a..a406fd434a0 100644 --- a/tests/run-pass/panic/catch_panic.rs +++ b/tests/run-pass/panic/catch_panic.rs @@ -69,10 +69,41 @@ fn main() { // libcore panics from shims. #[allow(deprecated, invalid_value)] - test( - Some("Attempted to instantiate uninhabited type !"), - |_old_val| unsafe { std::mem::uninitialized::() }, - ); + { + test( + Some("attempted to instantiate uninhabited type !"), + |_old_val| unsafe { std::mem::uninitialized::() }, + ); + test( + Some("attempted to zero-initialize type `!`, which is invalid"), + |_old_val| unsafe { std::mem::zeroed::() }, + ); + test( + Some("attempted to leave type `fn()` uninitialized, which is invalid"), + |_old_val| unsafe { std::mem::uninitialized::(); loop {} }, + ); + test( + Some("attempted to zero-initialize type `fn()`, which is invalid"), + |_old_val| unsafe { std::mem::zeroed::(); loop {} }, + ); + test( + Some("attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid"), + |_old_val| unsafe { std::mem::uninitialized::<*const dyn Sync>(); loop {} }, + ); + test( + Some("attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid"), + |_old_val| unsafe { std::mem::zeroed::<*mut dyn Sync>(); loop {} }, + ); + test( + Some("attempted to leave type `&u8` uninitialized, which is invalid"), + |_old_val| unsafe { std::mem::uninitialized::<&u8>(); loop {} }, + ); + test( + Some("attempted to zero-initialize type `&u8`, which is invalid"), + |_old_val| unsafe { std::mem::zeroed::<&u8>(); loop {} }, + ); + } + test( Some("align_offset: align is not a power-of-two"), |_old_val| { (0usize as *const u8).align_offset(3); loop {} }, diff --git a/tests/run-pass/panic/catch_panic.stderr b/tests/run-pass/panic/catch_panic.stderr index 4ff22fe2176..1899ea3c684 100644 --- a/tests/run-pass/panic/catch_panic.stderr +++ b/tests/run-pass/panic/catch_panic.stderr @@ -16,13 +16,27 @@ thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4' Caught panic message (String): index out of bounds: the len is 3 but the index is 4 thread 'main' panicked at 'attempt to divide by zero', $DIR/catch_panic.rs:67:33 Caught panic message (String): attempt to divide by zero -thread 'main' panicked at 'Attempted to instantiate uninhabited type !', $LOC -Caught panic message (String): Attempted to instantiate uninhabited type ! +thread 'main' panicked at 'attempted to instantiate uninhabited type !', $LOC +Caught panic message (String): attempted to instantiate uninhabited type ! +thread 'main' panicked at 'attempted to zero-initialize type `!`, which is invalid', $LOC +Caught panic message (String): attempted to zero-initialize type `!`, which is invalid +thread 'main' panicked at 'attempted to leave type `fn()` uninitialized, which is invalid', $LOC +Caught panic message (String): attempted to leave type `fn()` uninitialized, which is invalid +thread 'main' panicked at 'attempted to zero-initialize type `fn()`, which is invalid', $LOC +Caught panic message (String): attempted to zero-initialize type `fn()`, which is invalid +thread 'main' panicked at 'attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid', $LOC +Caught panic message (String): attempted to leave type `*const dyn std::marker::Sync` uninitialized, which is invalid +thread 'main' panicked at 'attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid', $LOC +Caught panic message (String): attempted to zero-initialize type `*mut dyn std::marker::Sync`, which is invalid +thread 'main' panicked at 'attempted to leave type `&u8` uninitialized, which is invalid', $LOC +Caught panic message (String): attempted to leave type `&u8` uninitialized, which is invalid +thread 'main' panicked at 'attempted to zero-initialize type `&u8`, which is invalid', $LOC +Caught panic message (String): attempted to zero-initialize type `&u8`, which is invalid thread 'main' panicked at 'align_offset: align is not a power-of-two', $LOC Caught panic message (String): align_offset: align is not a power-of-two -thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:82:29 +thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:113:29 Caught panic message (&str): assertion failed: false -thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:83:29 +thread 'main' panicked at 'assertion failed: false', $DIR/catch_panic.rs:114:29 Caught panic message (&str): assertion failed: false thread 'main' panicked at 'attempt to copy from unaligned or null pointer', $LOC Caught panic message (String): attempt to copy from unaligned or null pointer From 548c90e102fe46a8348bbf7cb06c92782c66a02a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 11 Mar 2020 19:52:39 +0100 Subject: [PATCH 4/4] share some code between panic intrinsics, and fix the message --- src/shims/intrinsics.rs | 33 +++++++------------------ tests/run-pass/panic/catch_panic.rs | 4 +-- tests/run-pass/panic/catch_panic.stderr | 8 +++--- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index d0305c0e9fb..fbb0a654294 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -444,35 +444,20 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx this.write_scalar(result_ptr, dest)?; } - "panic_if_uninhabited" => { - let ty = substs.type_at(0); - let layout = this.layout_of(ty)?; - if layout.abi.is_uninhabited() { - // Return here because we paniced instead of returning normally from the intrinsic. - return this.start_panic(&format!("attempted to instantiate uninhabited type {}", ty), unwind); - } - } - - "panic_if_zero_invalid" => { - let ty = substs.type_at(0); - let layout = this.layout_of(ty)?; - // Check if it permits zeroed raw initialization - if !layout.might_permit_raw_init(this, /*zero:*/ true).unwrap() { - // Return here because we paniced instead of returning normally from the intrinsic. - return this.start_panic(&format!("attempted to zero-initialize type `{}`, which is invalid", ty), unwind); - } - } - + "panic_if_uninhabited" | + "panic_if_zero_invalid" | "panic_if_any_invalid" => { let ty = substs.type_at(0); let layout = this.layout_of(ty)?; - // rustc handles all these in a single function, but we don't so we need to make sure `mem::uninitialized::()` returns the right error. - // So we check for `is_uninhabited` here too. if layout.abi.is_uninhabited() { - return this.start_panic(&format!("attempted to instantiate uninhabited type {}", ty), unwind); + // Return here because we paniced instead of returning normally from the intrinsic. + return this.start_panic(&format!("attempted to instantiate uninhabited type `{}`", ty), unwind); } - // Check if it permits any raw initialization - if !layout.might_permit_raw_init(this, /*zero:*/ false).unwrap() { + if intrinsic_name == "panic_if_zero_invalid" && !layout.might_permit_raw_init(this, /*zero:*/ true).unwrap() { + // Return here because we paniced instead of returning normally from the intrinsic. + return this.start_panic(&format!("attempted to zero-initialize type `{}`, which is invalid", ty), unwind); + } + if intrinsic_name == "panic_if_any_invalid" && !layout.might_permit_raw_init(this, /*zero:*/ false).unwrap() { // Return here because we paniced instead of returning normally from the intrinsic. return this.start_panic(&format!("attempted to leave type `{}` uninitialized, which is invalid", ty), unwind); } diff --git a/tests/run-pass/panic/catch_panic.rs b/tests/run-pass/panic/catch_panic.rs index a406fd434a0..cc97ba5a85d 100644 --- a/tests/run-pass/panic/catch_panic.rs +++ b/tests/run-pass/panic/catch_panic.rs @@ -71,11 +71,11 @@ fn main() { #[allow(deprecated, invalid_value)] { test( - Some("attempted to instantiate uninhabited type !"), + Some("attempted to instantiate uninhabited type `!`"), |_old_val| unsafe { std::mem::uninitialized::() }, ); test( - Some("attempted to zero-initialize type `!`, which is invalid"), + Some("attempted to instantiate uninhabited type `!`"), |_old_val| unsafe { std::mem::zeroed::() }, ); test( diff --git a/tests/run-pass/panic/catch_panic.stderr b/tests/run-pass/panic/catch_panic.stderr index 1899ea3c684..8d97fd6321f 100644 --- a/tests/run-pass/panic/catch_panic.stderr +++ b/tests/run-pass/panic/catch_panic.stderr @@ -16,10 +16,10 @@ thread 'main' panicked at 'index out of bounds: the len is 3 but the index is 4' Caught panic message (String): index out of bounds: the len is 3 but the index is 4 thread 'main' panicked at 'attempt to divide by zero', $DIR/catch_panic.rs:67:33 Caught panic message (String): attempt to divide by zero -thread 'main' panicked at 'attempted to instantiate uninhabited type !', $LOC -Caught panic message (String): attempted to instantiate uninhabited type ! -thread 'main' panicked at 'attempted to zero-initialize type `!`, which is invalid', $LOC -Caught panic message (String): attempted to zero-initialize type `!`, which is invalid +thread 'main' panicked at 'attempted to instantiate uninhabited type `!`', $LOC +Caught panic message (String): attempted to instantiate uninhabited type `!` +thread 'main' panicked at 'attempted to instantiate uninhabited type `!`', $LOC +Caught panic message (String): attempted to instantiate uninhabited type `!` thread 'main' panicked at 'attempted to leave type `fn()` uninitialized, which is invalid', $LOC Caught panic message (String): attempted to leave type `fn()` uninitialized, which is invalid thread 'main' panicked at 'attempted to zero-initialize type `fn()`, which is invalid', $LOC