Auto merge of #54667 - RalfJung:maybe-uninit, r=pnkfelix
Panic when using mem::uninitialized or mem::zeroed on an uninhabited type All code by @japaric. This re-submits one half of https://github.com/rust-lang/rust/pull/53508. This is likely not the one that introduced the perf regression, but just to be sure I'll do a perf run anyway.
This commit is contained in:
commit
de3d640f59
11 changed files with 181 additions and 14 deletions
23
src/test/codegen/box-maybe-uninit.rs
Normal file
23
src/test/codegen/box-maybe-uninit.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// compile-flags: -O
|
||||
#![crate_type="lib"]
|
||||
#![feature(maybe_uninit)]
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
// Boxing a `MaybeUninit` value should not copy junk from the stack
|
||||
#[no_mangle]
|
||||
pub fn box_uninitialized() -> Box<MaybeUninit<usize>> {
|
||||
// CHECK-LABEL: @box_uninitialized
|
||||
// CHECK-NOT: store
|
||||
Box::new(MaybeUninit::uninitialized())
|
||||
}
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// NOTE Instantiating an empty enum is UB. This test may break in the future.
|
||||
|
||||
// LLDB can't handle zero-sized values
|
||||
// ignore-lldb
|
||||
|
||||
|
|
@ -25,8 +27,11 @@
|
|||
|
||||
#![allow(unused_variables)]
|
||||
#![feature(omit_gdb_pretty_printer_section)]
|
||||
#![feature(maybe_uninit)]
|
||||
#![omit_gdb_pretty_printer_section]
|
||||
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
enum ANilEnum {}
|
||||
enum AnotherNilEnum {}
|
||||
|
||||
|
|
@ -35,8 +40,8 @@ enum AnotherNilEnum {}
|
|||
// The error from gdbr is expected since nil enums are not supposed to exist.
|
||||
fn main() {
|
||||
unsafe {
|
||||
let first: ANilEnum = ::std::mem::zeroed();
|
||||
let second: AnotherNilEnum = ::std::mem::zeroed();
|
||||
let first: ANilEnum = MaybeUninit::uninitialized().into_inner();
|
||||
let second: AnotherNilEnum = MaybeUninit::uninitialized().into_inner();
|
||||
|
||||
zzz(); // #break
|
||||
}
|
||||
|
|
|
|||
83
src/test/run-pass/panic-uninitialized-zeroed.rs
Normal file
83
src/test/run-pass/panic-uninitialized-zeroed.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// ignore-wasm32-bare always compiled as panic=abort right now and this requires unwinding
|
||||
// This test checks that instantiating an uninhabited type via `mem::{uninitialized,zeroed}` results
|
||||
// in a runtime panic.
|
||||
|
||||
#![feature(never_type)]
|
||||
|
||||
use std::{mem, panic};
|
||||
|
||||
#[allow(dead_code)]
|
||||
struct Foo {
|
||||
x: u8,
|
||||
y: !,
|
||||
}
|
||||
|
||||
enum Bar {}
|
||||
|
||||
fn main() {
|
||||
unsafe {
|
||||
assert_eq!(
|
||||
panic::catch_unwind(|| {
|
||||
mem::uninitialized::<!>()
|
||||
}).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
|
||||
s == "Attempted to instantiate uninhabited type ! using mem::uninitialized"
|
||||
})),
|
||||
Some(true)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
panic::catch_unwind(|| {
|
||||
mem::zeroed::<!>()
|
||||
}).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
|
||||
s == "Attempted to instantiate uninhabited type ! using mem::zeroed"
|
||||
})),
|
||||
Some(true)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
panic::catch_unwind(|| {
|
||||
mem::uninitialized::<Foo>()
|
||||
}).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
|
||||
s == "Attempted to instantiate uninhabited type Foo using mem::uninitialized"
|
||||
})),
|
||||
Some(true)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
panic::catch_unwind(|| {
|
||||
mem::zeroed::<Foo>()
|
||||
}).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
|
||||
s == "Attempted to instantiate uninhabited type Foo using mem::zeroed"
|
||||
})),
|
||||
Some(true)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
panic::catch_unwind(|| {
|
||||
mem::uninitialized::<Bar>()
|
||||
}).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
|
||||
s == "Attempted to instantiate uninhabited type Bar using mem::uninitialized"
|
||||
})),
|
||||
Some(true)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
panic::catch_unwind(|| {
|
||||
mem::zeroed::<Bar>()
|
||||
}).err().and_then(|a| a.downcast_ref::<String>().map(|s| {
|
||||
s == "Attempted to instantiate uninhabited type Bar using mem::zeroed"
|
||||
})),
|
||||
Some(true)
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue