2019-11-03 10:21:37 -06:00
|
|
|
// run-pass
|
|
|
|
// ignore-wasm32-bare compiled with panic=abort by default
|
2021-05-27 13:37:49 -05:00
|
|
|
// revisions: mir thir
|
|
|
|
// [thir]compile-flags: -Zthir-unsafeck
|
2021-09-20 11:22:55 -05:00
|
|
|
// ignore-tidy-linelength
|
2019-11-03 10:21:37 -06:00
|
|
|
|
|
|
|
// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
|
|
|
|
|
2021-10-14 09:57:56 -05:00
|
|
|
#![feature(never_type, arbitrary_enum_discriminant)]
|
2019-11-03 10:21:37 -06:00
|
|
|
#![allow(deprecated, invalid_value)]
|
|
|
|
|
2019-11-09 05:24:26 -06:00
|
|
|
use std::{
|
2020-02-17 02:21:02 -06:00
|
|
|
mem::{self, MaybeUninit, ManuallyDrop},
|
2019-11-09 05:24:26 -06:00
|
|
|
panic,
|
|
|
|
ptr::NonNull,
|
2020-02-17 02:21:02 -06:00
|
|
|
num,
|
2019-11-09 05:24:26 -06:00
|
|
|
};
|
2019-11-03 10:21:37 -06:00
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
struct Foo {
|
|
|
|
x: u8,
|
|
|
|
y: !,
|
|
|
|
}
|
|
|
|
|
|
|
|
enum Bar {}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
enum OneVariant { Variant(i32) }
|
|
|
|
|
2020-04-18 02:54:05 -05:00
|
|
|
#[allow(dead_code, non_camel_case_types)]
|
|
|
|
enum OneVariant_NonZero {
|
|
|
|
Variant(i32, i32, num::NonZeroI32),
|
|
|
|
DeadVariant(Bar),
|
|
|
|
}
|
|
|
|
|
|
|
|
// An `Aggregate` abi enum where 0 is not a valid discriminant.
|
|
|
|
#[allow(dead_code)]
|
|
|
|
#[repr(i32)]
|
|
|
|
enum NoNullVariant {
|
|
|
|
Variant1(i32, i32) = 1,
|
|
|
|
Variant2(i32, i32) = 2,
|
|
|
|
}
|
|
|
|
|
2020-02-17 02:21:02 -06:00
|
|
|
// An enum with ScalarPair layout
|
|
|
|
#[allow(dead_code)]
|
|
|
|
enum LR {
|
|
|
|
Left(i64),
|
|
|
|
Right(i64),
|
|
|
|
}
|
|
|
|
#[allow(dead_code, non_camel_case_types)]
|
|
|
|
enum LR_NonZero {
|
|
|
|
Left(num::NonZeroI64),
|
|
|
|
Right(num::NonZeroI64),
|
|
|
|
}
|
|
|
|
|
2019-11-03 10:21:37 -06:00
|
|
|
fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
|
|
|
|
let err = panic::catch_unwind(op).err();
|
|
|
|
assert_eq!(
|
2020-10-19 15:36:45 -05:00
|
|
|
err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
|
|
|
|
Some(&msg)
|
2019-11-03 10:21:37 -06:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
unsafe {
|
2020-02-17 02:21:02 -06:00
|
|
|
// Uninhabited types
|
2019-11-03 10:21:37 -06:00
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<!>(),
|
|
|
|
"attempted to instantiate uninhabited type `!`"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<!>(),
|
|
|
|
"attempted to instantiate uninhabited type `!`"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
2019-11-09 05:24:26 -06:00
|
|
|
|| MaybeUninit::<!>::uninit().assume_init(),
|
2019-11-03 10:21:37 -06:00
|
|
|
"attempted to instantiate uninhabited type `!`"
|
|
|
|
);
|
|
|
|
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<Foo>(),
|
|
|
|
"attempted to instantiate uninhabited type `Foo`"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<Foo>(),
|
|
|
|
"attempted to instantiate uninhabited type `Foo`"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
2019-11-09 05:24:26 -06:00
|
|
|
|| MaybeUninit::<Foo>::uninit().assume_init(),
|
2019-11-03 10:21:37 -06:00
|
|
|
"attempted to instantiate uninhabited type `Foo`"
|
|
|
|
);
|
|
|
|
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<Bar>(),
|
|
|
|
"attempted to instantiate uninhabited type `Bar`"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<Bar>(),
|
|
|
|
"attempted to instantiate uninhabited type `Bar`"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
2019-11-09 05:24:26 -06:00
|
|
|
|| MaybeUninit::<Bar>::uninit().assume_init(),
|
2019-11-03 10:21:37 -06:00
|
|
|
"attempted to instantiate uninhabited type `Bar`"
|
|
|
|
);
|
|
|
|
|
|
|
|
// Types that do not like zero-initialziation
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<fn()>(),
|
|
|
|
"attempted to leave type `fn()` uninitialized, which is invalid"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<fn()>(),
|
|
|
|
"attempted to zero-initialize type `fn()`, which is invalid"
|
|
|
|
);
|
|
|
|
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<*const dyn Send>(),
|
2021-09-20 11:22:55 -05:00
|
|
|
"attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
|
2019-11-03 10:21:37 -06:00
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<*const dyn Send>(),
|
2021-09-20 11:22:55 -05:00
|
|
|
"attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
|
2019-11-03 10:21:37 -06:00
|
|
|
);
|
|
|
|
|
2019-11-13 02:00:29 -06:00
|
|
|
/* FIXME(#66151) we conservatively do not error here yet.
|
2020-02-17 02:21:02 -06:00
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<LR_NonZero>(),
|
|
|
|
"attempted to leave type `LR_NonZero` uninitialized, which is invalid"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<LR_NonZero>(),
|
|
|
|
"attempted to zero-initialize type `LR_NonZero`, which is invalid"
|
|
|
|
);
|
|
|
|
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
|
|
|
|
"attempted to leave type `std::mem::ManuallyDrop<LR_NonZero>` uninitialized, \
|
|
|
|
which is invalid"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
|
|
|
|
"attempted to zero-initialize type `std::mem::ManuallyDrop<LR_NonZero>`, \
|
|
|
|
which is invalid"
|
|
|
|
);
|
2020-04-18 02:54:05 -05:00
|
|
|
*/
|
2020-02-17 02:21:02 -06:00
|
|
|
|
2019-11-03 10:21:37 -06:00
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
|
2021-09-20 11:22:55 -05:00
|
|
|
"attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
|
2019-11-03 10:21:37 -06:00
|
|
|
which is invalid"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<(NonNull<u32>, u32, u32)>(),
|
2021-09-20 11:22:55 -05:00
|
|
|
"attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
|
2019-11-03 10:21:37 -06:00
|
|
|
which is invalid"
|
|
|
|
);
|
2020-04-18 02:54:05 -05:00
|
|
|
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<OneVariant_NonZero>(),
|
|
|
|
"attempted to leave type `OneVariant_NonZero` uninitialized, \
|
|
|
|
which is invalid"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<OneVariant_NonZero>(),
|
|
|
|
"attempted to zero-initialize type `OneVariant_NonZero`, \
|
|
|
|
which is invalid"
|
|
|
|
);
|
|
|
|
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<NoNullVariant>(),
|
|
|
|
"attempted to leave type `NoNullVariant` uninitialized, \
|
|
|
|
which is invalid"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::zeroed::<NoNullVariant>(),
|
|
|
|
"attempted to zero-initialize type `NoNullVariant`, \
|
|
|
|
which is invalid"
|
|
|
|
);
|
2019-11-03 10:21:37 -06:00
|
|
|
|
2020-02-17 02:21:02 -06:00
|
|
|
// Types that can be zero, but not uninit.
|
2019-11-03 10:21:37 -06:00
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<bool>(),
|
|
|
|
"attempted to leave type `bool` uninitialized, which is invalid"
|
|
|
|
);
|
2020-02-17 02:21:02 -06:00
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<LR>(),
|
|
|
|
"attempted to leave type `LR` uninitialized, which is invalid"
|
|
|
|
);
|
|
|
|
test_panic_msg(
|
|
|
|
|| mem::uninitialized::<ManuallyDrop<LR>>(),
|
2021-09-20 11:22:55 -05:00
|
|
|
"attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
|
2020-02-17 02:21:02 -06:00
|
|
|
);
|
2019-11-03 10:21:37 -06:00
|
|
|
|
|
|
|
// Some things that should work.
|
|
|
|
let _val = mem::zeroed::<bool>();
|
2020-02-17 02:21:02 -06:00
|
|
|
let _val = mem::zeroed::<LR>();
|
|
|
|
let _val = mem::zeroed::<ManuallyDrop<LR>>();
|
2019-11-03 10:21:37 -06:00
|
|
|
let _val = mem::zeroed::<OneVariant>();
|
|
|
|
let _val = mem::zeroed::<Option<&'static i32>>();
|
2019-11-09 05:24:26 -06:00
|
|
|
let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
|
|
|
|
let _val = mem::uninitialized::<MaybeUninit<bool>>();
|
|
|
|
|
2020-02-29 02:29:51 -06:00
|
|
|
// These are UB because they have not been officially blessed, but we await the resolution
|
|
|
|
// of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
|
|
|
|
// anything about that.
|
2019-11-09 05:24:26 -06:00
|
|
|
let _val = mem::uninitialized::<i32>();
|
|
|
|
let _val = mem::uninitialized::<*const ()>();
|
2019-11-03 10:21:37 -06:00
|
|
|
}
|
|
|
|
}
|