Skip to content

Commit

Permalink
Auto merge of #2314 - RalfJung:unsized, r=RalfJung
Browse files Browse the repository at this point in the history
adjust for removed unsized_locals

The Miri side of rust-lang/rust#98831
  • Loading branch information
bors committed Jul 7, 2022
2 parents 4e4607b + 0ee78b9 commit 968b032
Show file tree
Hide file tree
Showing 12 changed files with 129 additions and 25 deletions.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7665c3543079ebc3710b676d0fd6951bedfd4b29
8824d131619e58a38bde8bcf56401629b91a204a
2 changes: 1 addition & 1 deletion src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ impl Provenance for Tag {
write!(f, "{:?}", sb)?;
}
Tag::Wildcard => {
write!(f, "[Wildcard]")?;
write!(f, "[wildcard]")?;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
Immediate::Scalar(l) => (l.check_init()?.to_bits(size)?, 0),
Immediate::ScalarPair(l1, l2) =>
(l1.check_init()?.to_bits(size)?, l2.check_init()?.to_bits(size)?),
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
};
let right = match **right {
Immediate::Scalar(r) => (r.check_init()?.to_bits(size)?, 0),
Immediate::ScalarPair(r1, r2) =>
(r1.check_init()?.to_bits(size)?, r2.check_init()?.to_bits(size)?),
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
};
let res = match bin_op {
Eq => left == right,
Expand Down
4 changes: 2 additions & 2 deletions src/shims/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
"volatile_load" => {
let [place] = check_arg_count(args)?;
let place = this.deref_operand(place)?;
this.copy_op(&place.into(), dest)?;
this.copy_op(&place.into(), dest, /*allow_transmute*/ false)?;
}
"volatile_store" => {
let [place, dest] = check_arg_count(args)?;
let place = this.deref_operand(place)?;
this.copy_op(dest, &place.into())?;
this.copy_op(dest, &place.into(), /*allow_transmute*/ false)?;
}

"write_bytes" | "volatile_set_memory" => {
Expand Down
25 changes: 25 additions & 0 deletions tests/fail/data_race/stack_pop_race.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// ignore-windows: Concurrency on Windows is not supported yet.
// compile-flags: -Zmiri-preemption-rate=0
use std::thread;

#[derive(Copy, Clone)]
struct MakeSend(*const i32);
unsafe impl Send for MakeSend {}

fn main() {
race(0);
}

// Using an argument for the ptr to point to, since those do not get StorageDead.
fn race(local: i32) {
let ptr = MakeSend(&local as *const i32);
thread::spawn(move || {
let ptr = ptr;
let _val = unsafe { *ptr.0 };
});
// Make the other thread go first so that it does not UAF.
thread::yield_now();
// Deallocating the local (when `main` returns)
// races with the read in the other thread.
// Make sure the error points at this function's end, not just the call site.
} //~ERROR Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>`
20 changes: 20 additions & 0 deletions tests/fail/data_race/stack_pop_race.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error: Undefined Behavior: Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>` at ALLOC
--> $DIR/stack_pop_race.rs:LL:CC
|
LL | }
| ^ Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>` at ALLOC
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: backtrace:
= note: inside `race` at $DIR/stack_pop_race.rs:LL:CC
note: inside `main` at $DIR/stack_pop_race.rs:LL:CC
--> $DIR/stack_pop_race.rs:LL:CC
|
LL | fn main() { race(0); }
| ^^^^^^^

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

23 changes: 23 additions & 0 deletions tests/fail/unsized-local.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![feature(unsized_locals)]
#![allow(incomplete_features)]

fn main() {
pub trait Foo {
fn foo(self) -> String;
}

struct A;

impl Foo for A {
fn foo(self) -> String {
format!("hello")
}
}

let x = *(Box::new(A) as Box<dyn Foo>); //~ERROR unsized locals are not supported
assert_eq!(x.foo(), format!("hello"));

// I'm not sure whether we want this to work
let x = Box::new(A) as Box<dyn Foo>;
assert_eq!(x.foo(), format!("hello"));
}
14 changes: 14 additions & 0 deletions tests/fail/unsized-local.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error: unsupported operation: unsized locals are not supported
--> $DIR/unsized-local.rs:LL:CC
|
LL | let x = *(Box::new(A) as Box<dyn Foo>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsized locals are not supported
|
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
= note: backtrace:
= note: inside `main` at $DIR/unsized-local.rs:LL:CC

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

12 changes: 4 additions & 8 deletions tests/pass/dyn-traits.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
#![feature(unsized_locals, unsized_fn_params)]
#![allow(incomplete_features)]

fn ref_box_dyn() {
struct Struct(i32);

Expand Down Expand Up @@ -75,6 +72,9 @@ fn box_box_trait() {
assert!(unsafe { DROPPED });
}

// Disabled for now: unsized locals are not supported,
// their current MIR encoding is just not great.
/*
fn unsized_dyn() {
pub trait Foo {
fn foo(self) -> String;
Expand All @@ -95,7 +95,6 @@ fn unsized_dyn() {
let x = Box::new(A) as Box<dyn Foo>;
assert_eq!(x.foo(), format!("hello"));
}

fn unsized_dyn_autoderef() {
pub trait Foo {
fn foo(self) -> String;
Expand Down Expand Up @@ -140,12 +139,9 @@ fn unsized_dyn_autoderef() {
let x = Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>;
assert_eq!(&x.foo() as &str, "hello");
}
*/

fn main() {
ref_box_dyn();
box_box_trait();

// "exotic" receivers
unsized_dyn();
unsized_dyn_autoderef();
}
1 change: 1 addition & 0 deletions tests/pass/transmute_fat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

fn main() {
// If we are careful, we can exploit data layout...
// This is a tricky case since we are transmuting a ScalarPair type to a non-ScalarPair type.
let raw = unsafe { std::mem::transmute::<&[u8], [*const u8; 2]>(&[42]) };
let ptr: *const u8 = unsafe { std::mem::transmute_copy(&raw) };
assert_eq!(unsafe { *ptr }, 42);
Expand Down
13 changes: 0 additions & 13 deletions tests/pass/unsized-tuple-impls.rs

This file was deleted.

36 changes: 36 additions & 0 deletions tests/pass/unsized.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#![feature(unsized_tuple_coercion)]
#![feature(unsized_fn_params)]

use std::mem;

fn unsized_tuple() {
let x: &(i32, i32, [i32]) = &(0, 1, [2, 3]);
let y: &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]);
let mut a = [y, x];
a.sort();
assert_eq!(a, [x, y]);

assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
assert_eq!(mem::size_of_val(x), 16);
}

fn unsized_params() {
pub fn f0(_f: dyn FnOnce()) {}
pub fn f1(_s: str) {}
pub fn f2(_x: i32, _y: [i32]) {}
pub fn f3(_p: dyn Send) {}

let c: Box<dyn FnOnce()> = Box::new(|| {});
f0(*c);
let foo = "foo".to_string().into_boxed_str();
f1(*foo);
let sl: Box<[i32]> = [0, 1, 2].to_vec().into_boxed_slice();
f2(5, *sl);
let p: Box<dyn Send> = Box::new((1, 2));
f3(*p);
}

fn main() {
unsized_tuple();
unsized_params();
}

0 comments on commit 968b032

Please sign in to comment.