Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adjust for removed unsized_locals #2314

Merged
merged 4 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 | 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();
}