mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
Rollup merge of #67507 - Mark-Simulacrum:purge-uninit, r=Centril
Remove mem::uninitalized from tests This purges uses of uninitialized where possible from test cases. Some are merely moved over to the equally bad pattern of MaybeUninit::uninit().assume_init() but with an annotation that this is "the best we can do". Fixes #62397
This commit is contained in:
commit
67c0f4e2c9
@ -7,3 +7,5 @@
|
||||
all:
|
||||
$(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) librustc_msan
|
||||
$(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value
|
||||
$(RUSTC) -g -Z sanitizer=memory -Z print-link-args maybeuninit.rs | $(CGREP) librustc_msan
|
||||
$(TMPDIR)/maybeuninit 2>&1 | $(CGREP) use-of-uninitialized-value
|
||||
|
@ -0,0 +1,8 @@
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
fn main() {
|
||||
// This is technically not sound -- but we're literally trying to test
|
||||
// that the sanitizer catches this, so I guess "intentionally unsound"?
|
||||
let xs: [u8; 4] = unsafe { MaybeUninit::uninit().assume_init() };
|
||||
let y = xs[0] + xs[1];
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use std::mem;
|
||||
|
||||
fn main() {
|
||||
// This is technically not sound -- but we're literally trying to test
|
||||
// that the sanitizer catches this, so I guess "intentionally unsound"?
|
||||
#[allow(deprecated)]
|
||||
let xs: [u8; 4] = unsafe { mem::uninitialized() };
|
||||
let xs: [u8; 4] = unsafe { std::mem::uninitialized() };
|
||||
let y = xs[0] + xs[1];
|
||||
}
|
||||
|
@ -105,8 +105,7 @@ impl<U: Unsigned, B: Bit> Add<B0> for UInt<U, B> {
|
||||
impl<U: Unsigned> Add<U> for UTerm {
|
||||
type Output = U;
|
||||
fn add(self, _: U) -> Self::Output {
|
||||
#[allow(deprecated)]
|
||||
unsafe { ::std::mem::uninitialized() }
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +136,7 @@ where
|
||||
{
|
||||
type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
|
||||
fn mul(self, _: UInt<Ur, B>) -> Self::Output {
|
||||
unsafe { ::std::mem::uninitialized() }
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
// ignore-sgx no processes
|
||||
// ignore-musl FIXME #31506
|
||||
|
||||
use std::mem;
|
||||
use std::mem::MaybeUninit;
|
||||
use std::process::Command;
|
||||
use std::thread;
|
||||
use std::env;
|
||||
@ -28,8 +28,8 @@ fn main() {
|
||||
let args = env::args().skip(1).collect::<Vec<_>>();
|
||||
if args.len() > 0 {
|
||||
match &args[0][..] {
|
||||
"main-thread" => recurse(&[]),
|
||||
"child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(),
|
||||
"main-thread" => recurse(&MaybeUninit::uninit()),
|
||||
"child-thread" => thread::spawn(|| recurse(&MaybeUninit::uninit())).join().unwrap(),
|
||||
_ => panic!(),
|
||||
}
|
||||
return
|
||||
@ -48,10 +48,11 @@ fn main() {
|
||||
}
|
||||
|
||||
#[allow(unconditional_recursion)]
|
||||
fn recurse(array: &[u64]) {
|
||||
unsafe { black_box(array.as_ptr() as u64); }
|
||||
#[allow(deprecated)]
|
||||
let local: [_; 1024] = unsafe { mem::uninitialized() };
|
||||
fn recurse(array: &MaybeUninit<[u64; 1024]>) {
|
||||
unsafe {
|
||||
black_box(array.as_ptr() as u64);
|
||||
}
|
||||
let local: MaybeUninit<[u64; 1024]> = MaybeUninit::uninit();
|
||||
recurse(&local);
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,10 @@
|
||||
|
||||
use std::mem;
|
||||
|
||||
// Neither of the uninits below are currently accepted as not UB, however,
|
||||
// this code does not run and is merely checking that we do not ICE on this pattern,
|
||||
// so this is fine.
|
||||
|
||||
fn foo<const SIZE: usize>() {
|
||||
let arr: [u8; SIZE] = unsafe {
|
||||
#[allow(deprecated)]
|
||||
@ -13,4 +17,12 @@ fn foo<const SIZE: usize>() {
|
||||
};
|
||||
}
|
||||
|
||||
fn bar<const SIZE: usize>() {
|
||||
let arr: [u8; SIZE] = unsafe {
|
||||
let array: [u8; SIZE] = mem::MaybeUninit::uninit().assume_init();
|
||||
array
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
|
@ -2,8 +2,8 @@
|
||||
fn main() {
|
||||
// Check that the tail statement in the body unifies with something
|
||||
for _ in 0..3 {
|
||||
#[allow(deprecated)]
|
||||
unsafe { std::mem::uninitialized() }
|
||||
// `()` is fine to zero-initialize as it is zero sized and inhabited.
|
||||
unsafe { std::mem::zeroed() }
|
||||
}
|
||||
|
||||
// Check that the tail statement in the body can be unit
|
||||
|
@ -1,7 +1,7 @@
|
||||
// This note is annotated because the purpose of the test
|
||||
// is to ensure that certain other notes are not generated.
|
||||
#![deny(unused_unsafe)] //~ NOTE
|
||||
#![allow(deprecated)]
|
||||
|
||||
|
||||
// (test that no note is generated on this unsafe fn)
|
||||
pub unsafe fn a() {
|
||||
@ -20,8 +20,8 @@ pub fn b() {
|
||||
unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe`
|
||||
//~^ NOTE
|
||||
}
|
||||
|
||||
let () = ::std::mem::uninitialized();
|
||||
// `()` is fine to zero-initialize as it is zero sized and inhabited.
|
||||
let () = ::std::mem::zeroed();
|
||||
|
||||
inner()
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
// run-pass
|
||||
// check-pass
|
||||
|
||||
trait FromUnchecked {
|
||||
unsafe fn from_unchecked();
|
||||
fn from_unchecked();
|
||||
}
|
||||
|
||||
impl FromUnchecked for [u8; 1] {
|
||||
unsafe fn from_unchecked() {
|
||||
#[allow(deprecated)]
|
||||
let mut array: Self = std::mem::uninitialized();
|
||||
fn from_unchecked() {
|
||||
let mut array: Self = [0; 1];
|
||||
let _ptr = &mut array as *mut [u8] as *mut u8;
|
||||
}
|
||||
}
|
||||
|
@ -69,8 +69,10 @@ fn main() {
|
||||
unsafe {
|
||||
// This should be safe, because we don't match on it unless it's fully formed,
|
||||
// and it doesn't have a destructor.
|
||||
#[allow(deprecated)]
|
||||
let mut dest: MyEnum = mem::uninitialized();
|
||||
//
|
||||
// MyEnum is repr(C, u8) so it is guaranteed to have a separate discriminant and each
|
||||
// variant can be zero initialized.
|
||||
let mut dest: MyEnum = mem::zeroed();
|
||||
while buf.len() > 0 {
|
||||
match parse_my_enum(&mut dest, &mut buf) {
|
||||
Ok(()) => output.push(Ok(dest)),
|
||||
|
@ -69,8 +69,11 @@ fn main() {
|
||||
unsafe {
|
||||
// This should be safe, because we don't match on it unless it's fully formed,
|
||||
// and it doesn't have a destructor.
|
||||
#[allow(deprecated)]
|
||||
let mut dest: MyEnum = mem::uninitialized();
|
||||
//
|
||||
// Furthermore, there are no types within MyEnum which cannot be initialized with zero,
|
||||
// specifically, though padding and such are present, there are no references or similar
|
||||
// types.
|
||||
let mut dest: MyEnum = mem::zeroed();
|
||||
while buf.len() > 0 {
|
||||
match parse_my_enum(&mut dest, &mut buf) {
|
||||
Ok(()) => output.push(Ok(dest)),
|
||||
|
@ -65,8 +65,10 @@ fn main() {
|
||||
unsafe {
|
||||
// This should be safe, because we don't match on it unless it's fully formed,
|
||||
// and it doesn't have a destructor.
|
||||
#[allow(deprecated)]
|
||||
let mut dest: MyEnum = mem::uninitialized();
|
||||
//
|
||||
// MyEnum is repr(u8) so it is guaranteed to have a separate discriminant and each variant
|
||||
// can be zero initialized.
|
||||
let mut dest: MyEnum = mem::zeroed();
|
||||
while buf.len() > 0 {
|
||||
match parse_my_enum(&mut dest, &mut buf) {
|
||||
Ok(()) => output.push(Ok(dest)),
|
||||
|
@ -1,5 +1,4 @@
|
||||
#![allow(deprecated)]
|
||||
|
||||
use std::mem::zeroed;
|
||||
enum Void {}
|
||||
|
||||
fn main() {
|
||||
@ -8,21 +7,25 @@ fn main() {
|
||||
Ok(n) => n,
|
||||
};
|
||||
|
||||
let x: &Void = unsafe { std::mem::uninitialized() };
|
||||
// This is pretty much instant UB. However, we have no choice -- we need to
|
||||
// test matching on a reference to `&Void`; we cannot do anything other than
|
||||
// just accept the fact that this is UB if `main` did run, but it doesn't;
|
||||
// this test only checks that these are feature-gated.
|
||||
let x: &Void = unsafe { zeroed() };
|
||||
let _ = match x {}; //~ ERROR non-exhaustive
|
||||
|
||||
let x: (Void,) = unsafe { std::mem::uninitialized() };
|
||||
let x: (Void,) = unsafe { zeroed() };
|
||||
let _ = match x {}; //~ ERROR non-exhaustive
|
||||
|
||||
let x: [Void; 1] = unsafe { std::mem::uninitialized() };
|
||||
let x: [Void; 1] = unsafe { zeroed() };
|
||||
let _ = match x {}; //~ ERROR non-exhaustive
|
||||
|
||||
let x: &[Void] = unsafe { std::mem::uninitialized() };
|
||||
let x: &[Void] = unsafe { zeroed() };
|
||||
let _ = match x { //~ ERROR non-exhaustive
|
||||
&[] => (),
|
||||
};
|
||||
|
||||
let x: Void = unsafe { std::mem::uninitialized() };
|
||||
let x: Void = unsafe { zeroed() };
|
||||
let _ = match x {}; // okay
|
||||
|
||||
let x: Result<u32, Void> = Ok(23);
|
||||
|
@ -1,5 +1,5 @@
|
||||
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:7:19
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:6:19
|
||||
|
|
||||
LL | let _ = match x {
|
||||
| ^ pattern `Err(_)` not covered
|
||||
@ -7,7 +7,7 @@ LL | let _ = match x {
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:12:19
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:15:19
|
||||
|
|
||||
LL | enum Void {}
|
||||
| ------------ `Void` defined here
|
||||
@ -18,14 +18,6 @@ LL | let _ = match x {};
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `(Void,)` is non-empty
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:15:19
|
||||
|
|
||||
LL | let _ = match x {};
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:18:19
|
||||
|
|
||||
LL | let _ = match x {};
|
||||
@ -33,16 +25,24 @@ LL | let _ = match x {};
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
|
||||
error[E0004]: non-exhaustive patterns: type `[Void; 1]` is non-empty
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:21:19
|
||||
|
|
||||
LL | let _ = match x {};
|
||||
| ^
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:24:19
|
||||
|
|
||||
LL | let _ = match x {
|
||||
| ^ pattern `&[_, ..]` not covered
|
||||
|
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:29:19
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:32:19
|
||||
|
|
||||
LL | let _ = match x {
|
||||
| ^ pattern `Err(_)` not covered
|
||||
@ -50,7 +50,7 @@ LL | let _ = match x {
|
||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
||||
|
||||
error[E0005]: refutable pattern in local binding: `Err(_)` not covered
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:34:9
|
||||
--> $DIR/uninhabited-matches-feature-gated.rs:37:9
|
||||
|
|
||||
LL | let Ok(x) = x;
|
||||
| ^^^^^ pattern `Err(_)` not covered
|
||||
|
@ -1,17 +1,19 @@
|
||||
// run-pass
|
||||
// build-pass
|
||||
// Test the uninit() construct returning various empty types.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
|
||||
use std::mem;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Foo;
|
||||
|
||||
#[allow(deprecated)]
|
||||
pub fn main() {
|
||||
unsafe {
|
||||
let _x: Foo = mem::uninitialized();
|
||||
let _x: [Foo; 2] = mem::uninitialized();
|
||||
// `Foo` and `[Foo; 2]` are both zero sized and inhabited, so this is safe.
|
||||
let _x: Foo = MaybeUninit::uninit().assume_init();
|
||||
let _x: [Foo; 2] = MaybeUninit::uninit().assume_init();
|
||||
let _x: Foo = std::mem::uninitialized();
|
||||
let _x: [Foo; 2] = std::mem::uninitialized();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user