mirror of https://github.com/rust-lang/rust.git
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".
This commit is contained in:
parent
3982d3514e
commit
c205f6a06a
|
@ -7,3 +7,5 @@
|
||||||
all:
|
all:
|
||||||
$(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) librustc_msan
|
$(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) librustc_msan
|
||||||
$(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value
|
$(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() {
|
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)]
|
#[allow(deprecated)]
|
||||||
let xs: [u8; 4] = unsafe { mem::uninitialized() };
|
let xs: [u8; 4] = unsafe { std::mem::uninitialized() };
|
||||||
let y = xs[0] + xs[1];
|
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 {
|
impl<U: Unsigned> Add<U> for UTerm {
|
||||||
type Output = U;
|
type Output = U;
|
||||||
fn add(self, _: U) -> Self::Output {
|
fn add(self, _: U) -> Self::Output {
|
||||||
#[allow(deprecated)]
|
unimplemented!()
|
||||||
unsafe { ::std::mem::uninitialized() }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +136,7 @@ where
|
||||||
{
|
{
|
||||||
type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
|
type Output = UInt<Prod<Ul, UInt<Ur, B>>, B0>;
|
||||||
fn mul(self, _: UInt<Ur, B>) -> Self::Output {
|
fn mul(self, _: UInt<Ur, B>) -> Self::Output {
|
||||||
unsafe { ::std::mem::uninitialized() }
|
unimplemented!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// ignore-sgx no processes
|
// ignore-sgx no processes
|
||||||
// ignore-musl FIXME #31506
|
// ignore-musl FIXME #31506
|
||||||
|
|
||||||
use std::mem;
|
use std::mem::MaybeUninit;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -28,8 +28,8 @@ fn main() {
|
||||||
let args = env::args().skip(1).collect::<Vec<_>>();
|
let args = env::args().skip(1).collect::<Vec<_>>();
|
||||||
if args.len() > 0 {
|
if args.len() > 0 {
|
||||||
match &args[0][..] {
|
match &args[0][..] {
|
||||||
"main-thread" => recurse(&[]),
|
"main-thread" => recurse(&MaybeUninit::uninit()),
|
||||||
"child-thread" => thread::spawn(|| recurse(&[])).join().unwrap(),
|
"child-thread" => thread::spawn(|| recurse(&MaybeUninit::uninit())).join().unwrap(),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -48,10 +48,11 @@ fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unconditional_recursion)]
|
#[allow(unconditional_recursion)]
|
||||||
fn recurse(array: &[u64]) {
|
fn recurse(array: &MaybeUninit<[u64; 1024]>) {
|
||||||
unsafe { black_box(array.as_ptr() as u64); }
|
unsafe {
|
||||||
#[allow(deprecated)]
|
black_box(array.as_ptr() as u64);
|
||||||
let local: [_; 1024] = unsafe { mem::uninitialized() };
|
}
|
||||||
|
let local: MaybeUninit<[u64; 1024]> = MaybeUninit::uninit();
|
||||||
recurse(&local);
|
recurse(&local);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
|
|
||||||
use std::mem;
|
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>() {
|
fn foo<const SIZE: usize>() {
|
||||||
let arr: [u8; SIZE] = unsafe {
|
let arr: [u8; SIZE] = unsafe {
|
||||||
#[allow(deprecated)]
|
#[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() {}
|
fn main() {}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
// Check that the tail statement in the body unifies with something
|
// Check that the tail statement in the body unifies with something
|
||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
#[allow(deprecated)]
|
// `()` is fine to zero-initialize as it is zero sized and inhabited.
|
||||||
unsafe { std::mem::uninitialized() }
|
unsafe { std::mem::zeroed() }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that the tail statement in the body can be unit
|
// 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
|
// This note is annotated because the purpose of the test
|
||||||
// is to ensure that certain other notes are not generated.
|
// is to ensure that certain other notes are not generated.
|
||||||
#![deny(unused_unsafe)] //~ NOTE
|
#![deny(unused_unsafe)] //~ NOTE
|
||||||
#![allow(deprecated)]
|
|
||||||
|
|
||||||
// (test that no note is generated on this unsafe fn)
|
// (test that no note is generated on this unsafe fn)
|
||||||
pub unsafe fn a() {
|
pub unsafe fn a() {
|
||||||
|
@ -20,8 +20,8 @@ pub fn b() {
|
||||||
unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe`
|
unsafe { /* unnecessary */ } //~ ERROR unnecessary `unsafe`
|
||||||
//~^ NOTE
|
//~^ NOTE
|
||||||
}
|
}
|
||||||
|
// `()` is fine to zero-initialize as it is zero sized and inhabited.
|
||||||
let () = ::std::mem::uninitialized();
|
let () = ::std::mem::zeroed();
|
||||||
|
|
||||||
inner()
|
inner()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
// run-pass
|
// check-pass
|
||||||
|
|
||||||
trait FromUnchecked {
|
trait FromUnchecked {
|
||||||
unsafe fn from_unchecked();
|
fn from_unchecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromUnchecked for [u8; 1] {
|
impl FromUnchecked for [u8; 1] {
|
||||||
unsafe fn from_unchecked() {
|
fn from_unchecked() {
|
||||||
#[allow(deprecated)]
|
let mut array: Self = [0; 1];
|
||||||
let mut array: Self = std::mem::uninitialized();
|
|
||||||
let _ptr = &mut array as *mut [u8] as *mut u8;
|
let _ptr = &mut array as *mut [u8] as *mut u8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,8 +69,10 @@ fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
// This should be safe, because we don't match on it unless it's fully formed,
|
// This should be safe, because we don't match on it unless it's fully formed,
|
||||||
// and it doesn't have a destructor.
|
// 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 {
|
while buf.len() > 0 {
|
||||||
match parse_my_enum(&mut dest, &mut buf) {
|
match parse_my_enum(&mut dest, &mut buf) {
|
||||||
Ok(()) => output.push(Ok(dest)),
|
Ok(()) => output.push(Ok(dest)),
|
||||||
|
|
|
@ -69,8 +69,11 @@ fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
// This should be safe, because we don't match on it unless it's fully formed,
|
// This should be safe, because we don't match on it unless it's fully formed,
|
||||||
// and it doesn't have a destructor.
|
// 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 {
|
while buf.len() > 0 {
|
||||||
match parse_my_enum(&mut dest, &mut buf) {
|
match parse_my_enum(&mut dest, &mut buf) {
|
||||||
Ok(()) => output.push(Ok(dest)),
|
Ok(()) => output.push(Ok(dest)),
|
||||||
|
|
|
@ -65,8 +65,10 @@ fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
// This should be safe, because we don't match on it unless it's fully formed,
|
// This should be safe, because we don't match on it unless it's fully formed,
|
||||||
// and it doesn't have a destructor.
|
// 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 {
|
while buf.len() > 0 {
|
||||||
match parse_my_enum(&mut dest, &mut buf) {
|
match parse_my_enum(&mut dest, &mut buf) {
|
||||||
Ok(()) => output.push(Ok(dest)),
|
Ok(()) => output.push(Ok(dest)),
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#![allow(deprecated)]
|
use std::mem::zeroed;
|
||||||
|
|
||||||
enum Void {}
|
enum Void {}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -8,21 +7,25 @@ fn main() {
|
||||||
Ok(n) => n,
|
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 _ = match x {}; //~ ERROR non-exhaustive
|
||||||
|
|
||||||
let x: (Void,) = unsafe { std::mem::uninitialized() };
|
let x: (Void,) = unsafe { zeroed() };
|
||||||
let _ = match x {}; //~ ERROR non-exhaustive
|
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 _ = match x {}; //~ ERROR non-exhaustive
|
||||||
|
|
||||||
let x: &[Void] = unsafe { std::mem::uninitialized() };
|
let x: &[Void] = unsafe { zeroed() };
|
||||||
let _ = match x { //~ ERROR non-exhaustive
|
let _ = match x { //~ ERROR non-exhaustive
|
||||||
&[] => (),
|
&[] => (),
|
||||||
};
|
};
|
||||||
|
|
||||||
let x: Void = unsafe { std::mem::uninitialized() };
|
let x: Void = unsafe { zeroed() };
|
||||||
let _ = match x {}; // okay
|
let _ = match x {}; // okay
|
||||||
|
|
||||||
let x: Result<u32, Void> = Ok(23);
|
let x: Result<u32, Void> = Ok(23);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
|
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 {
|
LL | let _ = match x {
|
||||||
| ^ pattern `Err(_)` not covered
|
| ^ 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
|
= 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
|
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 {}
|
LL | enum Void {}
|
||||||
| ------------ `Void` defined here
|
| ------------ `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
|
= 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
|
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
|
--> $DIR/uninhabited-matches-feature-gated.rs:18:19
|
||||||
|
|
|
|
||||||
LL | let _ = match x {};
|
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
|
= 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
|
--> $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 {
|
LL | let _ = match x {
|
||||||
| ^ pattern `&[_, ..]` not covered
|
| ^ pattern `&[_, ..]` not covered
|
||||||
|
|
|
|
||||||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
|
= 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
|
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 {
|
LL | let _ = match x {
|
||||||
| ^ pattern `Err(_)` not covered
|
| ^ 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
|
= 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
|
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;
|
LL | let Ok(x) = x;
|
||||||
| ^^^^^ pattern `Err(_)` not covered
|
| ^^^^^ pattern `Err(_)` not covered
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
// run-pass
|
// build-pass
|
||||||
// Test the uninit() construct returning various empty types.
|
// Test the uninit() construct returning various empty types.
|
||||||
|
|
||||||
// pretty-expanded FIXME #23616
|
// pretty-expanded FIXME #23616
|
||||||
|
|
||||||
use std::mem;
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct Foo;
|
struct Foo;
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _x: Foo = mem::uninitialized();
|
// `Foo` and `[Foo; 2]` are both zero sized and inhabited, so this is safe.
|
||||||
let _x: [Foo; 2] = mem::uninitialized();
|
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