share some code between panic intrinsics, and fix the message

This commit is contained in:
Ralf Jung 2020-03-11 19:52:39 +01:00
parent 2802c3cf0b
commit 548c90e102
3 changed files with 15 additions and 30 deletions

View File

@ -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);
}

View File

@ -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(

View File

@ -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