Skip to content

Commit 64dec22

Browse files
committed
Auto merge of rust-lang#2314 - RalfJung:unsized, r=RalfJung
adjust for removed unsized_locals The Miri side of rust-lang#98831
2 parents 4e4607b + b6602f5 commit 64dec22

12 files changed

+129
-25
lines changed

rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7665c3543079ebc3710b676d0fd6951bedfd4b29
1+
8824d131619e58a38bde8bcf56401629b91a204a

src/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ impl Provenance for Tag {
169169
write!(f, "{:?}", sb)?;
170170
}
171171
Tag::Wildcard => {
172-
write!(f, "[Wildcard]")?;
172+
write!(f, "[wildcard]")?;
173173
}
174174
}
175175

src/operator.rs

+2
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriEvalContext<'mir, 'tcx> {
3535
Immediate::Scalar(l) => (l.check_init()?.to_bits(size)?, 0),
3636
Immediate::ScalarPair(l1, l2) =>
3737
(l1.check_init()?.to_bits(size)?, l2.check_init()?.to_bits(size)?),
38+
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
3839
};
3940
let right = match **right {
4041
Immediate::Scalar(r) => (r.check_init()?.to_bits(size)?, 0),
4142
Immediate::ScalarPair(r1, r2) =>
4243
(r1.check_init()?.to_bits(size)?, r2.check_init()?.to_bits(size)?),
44+
Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
4345
};
4446
let res = match bin_op {
4547
Eq => left == right,

src/shims/intrinsics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6868
"volatile_load" => {
6969
let [place] = check_arg_count(args)?;
7070
let place = this.deref_operand(place)?;
71-
this.copy_op(&place.into(), dest)?;
71+
this.copy_op(&place.into(), dest, /*allow_transmute*/ false)?;
7272
}
7373
"volatile_store" => {
7474
let [place, dest] = check_arg_count(args)?;
7575
let place = this.deref_operand(place)?;
76-
this.copy_op(dest, &place.into())?;
76+
this.copy_op(dest, &place.into(), /*allow_transmute*/ false)?;
7777
}
7878

7979
"write_bytes" | "volatile_set_memory" => {
+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// ignore-windows: Concurrency on Windows is not supported yet.
2+
// compile-flags: -Zmiri-preemption-rate=0
3+
use std::thread;
4+
5+
#[derive(Copy, Clone)]
6+
struct MakeSend(*const i32);
7+
unsafe impl Send for MakeSend {}
8+
9+
fn main() {
10+
race(0);
11+
}
12+
13+
// Using an argument for the ptr to point to, since those do not get StorageDead.
14+
fn race(local: i32) {
15+
let ptr = MakeSend(&local as *const i32);
16+
thread::spawn(move || {
17+
let ptr = ptr;
18+
let _val = unsafe { *ptr.0 };
19+
});
20+
// Make the other thread go first so that it does not UAF.
21+
thread::yield_now();
22+
// Deallocating the local (when `main` returns)
23+
// races with the read in the other thread.
24+
// Make sure the error points at this function's end, not just the call site.
25+
} //~ERROR Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>`
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error: Undefined Behavior: Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>` at ALLOC
2+
--> $DIR/stack_pop_race.rs:LL:CC
3+
|
4+
LL | }
5+
| ^ Data race detected between Deallocate on thread `main` and Read on thread `<unnamed>` at ALLOC
6+
|
7+
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
8+
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
9+
= note: backtrace:
10+
= note: inside `race` at $DIR/stack_pop_race.rs:LL:CC
11+
note: inside `main` at $DIR/stack_pop_race.rs:LL:CC
12+
--> $DIR/stack_pop_race.rs:LL:CC
13+
|
14+
LL | race(0);
15+
| ^^^^^^^
16+
17+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
18+
19+
error: aborting due to previous error
20+

tests/fail/unsized-local.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#![feature(unsized_locals)]
2+
#![allow(incomplete_features)]
3+
4+
fn main() {
5+
pub trait Foo {
6+
fn foo(self) -> String;
7+
}
8+
9+
struct A;
10+
11+
impl Foo for A {
12+
fn foo(self) -> String {
13+
format!("hello")
14+
}
15+
}
16+
17+
let x = *(Box::new(A) as Box<dyn Foo>); //~ERROR unsized locals are not supported
18+
assert_eq!(x.foo(), format!("hello"));
19+
20+
// I'm not sure whether we want this to work
21+
let x = Box::new(A) as Box<dyn Foo>;
22+
assert_eq!(x.foo(), format!("hello"));
23+
}

tests/fail/unsized-local.stderr

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unsupported operation: unsized locals are not supported
2+
--> $DIR/unsized-local.rs:LL:CC
3+
|
4+
LL | let x = *(Box::new(A) as Box<dyn Foo>);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsized locals are not supported
6+
|
7+
= help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
8+
= note: backtrace:
9+
= note: inside `main` at $DIR/unsized-local.rs:LL:CC
10+
11+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
12+
13+
error: aborting due to previous error
14+

tests/pass/dyn-traits.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
#![feature(unsized_locals, unsized_fn_params)]
2-
#![allow(incomplete_features)]
3-
41
fn ref_box_dyn() {
52
struct Struct(i32);
63

@@ -75,6 +72,9 @@ fn box_box_trait() {
7572
assert!(unsafe { DROPPED });
7673
}
7774

75+
// Disabled for now: unsized locals are not supported,
76+
// their current MIR encoding is just not great.
77+
/*
7878
fn unsized_dyn() {
7979
pub trait Foo {
8080
fn foo(self) -> String;
@@ -95,7 +95,6 @@ fn unsized_dyn() {
9595
let x = Box::new(A) as Box<dyn Foo>;
9696
assert_eq!(x.foo(), format!("hello"));
9797
}
98-
9998
fn unsized_dyn_autoderef() {
10099
pub trait Foo {
101100
fn foo(self) -> String;
@@ -140,12 +139,9 @@ fn unsized_dyn_autoderef() {
140139
let x = Box::new(|| "hello".to_owned()) as Box<dyn FnMut() -> String>;
141140
assert_eq!(&x.foo() as &str, "hello");
142141
}
142+
*/
143143

144144
fn main() {
145145
ref_box_dyn();
146146
box_box_trait();
147-
148-
// "exotic" receivers
149-
unsized_dyn();
150-
unsized_dyn_autoderef();
151147
}

tests/pass/transmute_fat.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
fn main() {
55
// If we are careful, we can exploit data layout...
6+
// This is a tricky case since we are transmuting a ScalarPair type to a non-ScalarPair type.
67
let raw = unsafe { std::mem::transmute::<&[u8], [*const u8; 2]>(&[42]) };
78
let ptr: *const u8 = unsafe { std::mem::transmute_copy(&raw) };
89
assert_eq!(unsafe { *ptr }, 42);

tests/pass/unsized-tuple-impls.rs

-13
This file was deleted.

tests/pass/unsized.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![feature(unsized_tuple_coercion)]
2+
#![feature(unsized_fn_params)]
3+
4+
use std::mem;
5+
6+
fn unsized_tuple() {
7+
let x: &(i32, i32, [i32]) = &(0, 1, [2, 3]);
8+
let y: &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]);
9+
let mut a = [y, x];
10+
a.sort();
11+
assert_eq!(a, [x, y]);
12+
13+
assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
14+
assert_eq!(mem::size_of_val(x), 16);
15+
}
16+
17+
fn unsized_params() {
18+
pub fn f0(_f: dyn FnOnce()) {}
19+
pub fn f1(_s: str) {}
20+
pub fn f2(_x: i32, _y: [i32]) {}
21+
pub fn f3(_p: dyn Send) {}
22+
23+
let c: Box<dyn FnOnce()> = Box::new(|| {});
24+
f0(*c);
25+
let foo = "foo".to_string().into_boxed_str();
26+
f1(*foo);
27+
let sl: Box<[i32]> = [0, 1, 2].to_vec().into_boxed_slice();
28+
f2(5, *sl);
29+
let p: Box<dyn Send> = Box::new((1, 2));
30+
f3(*p);
31+
}
32+
33+
fn main() {
34+
unsized_tuple();
35+
unsized_params();
36+
}

0 commit comments

Comments
 (0)