Skip to content

Commit c1bbf07

Browse files
committed
Auto merge of #2040 - RalfJung:pnvi, r=RalfJung
ensure that -Zmiri-check-number-validity detects integers with provenance This actually currently *fails* for the non-array case; I will have to fix this on the rustc side.
2 parents 80fe3b1 + f3c35d5 commit c1bbf07

File tree

12 files changed

+96
-68
lines changed

12 files changed

+96
-68
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
d2df372bca13bb60979c909660e69f2451630e81
1+
100f12d17026fccfc5d80527b5976dd66b228b13

src/machine.rs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@ use std::time::Instant;
1010
use rand::rngs::StdRng;
1111
use rand::SeedableRng;
1212

13+
use rustc_ast::ast::Mutability;
1314
use rustc_data_structures::fx::FxHashMap;
1415
use rustc_middle::{
1516
mir,
1617
ty::{
1718
self,
1819
layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout},
19-
Instance, TyCtxt,
20+
Instance, TyCtxt, TypeAndMut,
2021
},
2122
};
2223
use rustc_span::def_id::{CrateNum, DefId};
@@ -269,19 +270,23 @@ pub struct PrimitiveLayouts<'tcx> {
269270
pub u32: TyAndLayout<'tcx>,
270271
pub usize: TyAndLayout<'tcx>,
271272
pub bool: TyAndLayout<'tcx>,
273+
pub mut_raw_ptr: TyAndLayout<'tcx>,
272274
}
273275

274276
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
275277
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, LayoutError<'tcx>> {
278+
let tcx = layout_cx.tcx;
279+
let mut_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
276280
Ok(Self {
277-
unit: layout_cx.layout_of(layout_cx.tcx.mk_unit())?,
278-
i8: layout_cx.layout_of(layout_cx.tcx.types.i8)?,
279-
i32: layout_cx.layout_of(layout_cx.tcx.types.i32)?,
280-
isize: layout_cx.layout_of(layout_cx.tcx.types.isize)?,
281-
u8: layout_cx.layout_of(layout_cx.tcx.types.u8)?,
282-
u32: layout_cx.layout_of(layout_cx.tcx.types.u32)?,
283-
usize: layout_cx.layout_of(layout_cx.tcx.types.usize)?,
284-
bool: layout_cx.layout_of(layout_cx.tcx.types.bool)?,
281+
unit: layout_cx.layout_of(tcx.mk_unit())?,
282+
i8: layout_cx.layout_of(tcx.types.i8)?,
283+
i32: layout_cx.layout_of(tcx.types.i32)?,
284+
isize: layout_cx.layout_of(tcx.types.isize)?,
285+
u8: layout_cx.layout_of(tcx.types.u8)?,
286+
u32: layout_cx.layout_of(tcx.types.u32)?,
287+
usize: layout_cx.layout_of(tcx.types.usize)?,
288+
bool: layout_cx.layout_of(tcx.types.bool)?,
289+
mut_raw_ptr: layout_cx.layout_of(mut_raw_ptr)?,
285290
})
286291
}
287292
}

src/shims/backtrace.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::*;
22
use rustc_ast::ast::Mutability;
33
use rustc_middle::ty::layout::LayoutOf as _;
4-
use rustc_middle::ty::{self, Instance, TypeAndMut};
4+
use rustc_middle::ty::{self, Instance};
55
use rustc_span::{BytePos, Loc, Symbol};
66
use rustc_target::{abi::Size, spec::abi::Abi};
77
use std::convert::TryInto as _;
@@ -71,8 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
7171

7272
let len: u64 = ptrs.len().try_into().unwrap();
7373

74-
let ptr_ty = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
75-
74+
let ptr_ty = this.machine.layouts.mut_raw_ptr.ty;
7675
let array_layout = this.layout_of(tcx.mk_array(ptr_ty, len)).unwrap();
7776

7877
match flags {

src/shims/env.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
440440
} else {
441441
// No `environ` allocated yet, let's do that.
442442
// This is memory backing an extern static, hence `ExternStatic`, not `Env`.
443-
let layout = this.machine.layouts.usize;
443+
let layout = this.machine.layouts.mut_raw_ptr;
444444
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
445445
this.machine.env_vars.environ = Some(place);
446446
}
@@ -452,8 +452,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
452452
vars.push(Pointer::null());
453453
// Make an array with all these pointers inside Miri.
454454
let tcx = this.tcx;
455-
let vars_layout =
456-
this.layout_of(tcx.mk_array(tcx.types.usize, u64::try_from(vars.len()).unwrap()))?;
455+
let vars_layout = this.layout_of(
456+
tcx.mk_array(this.machine.layouts.mut_raw_ptr.ty, u64::try_from(vars.len()).unwrap()),
457+
)?;
457458
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Runtime.into())?;
458459
for (idx, var) in vars.into_iter().enumerate() {
459460
let place = this.mplace_field(&vars_place, idx)?;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: -Zmiri-check-number-validity
2+
3+
fn main() {
4+
let r = &mut 42;
5+
let _i: [usize; 1] = unsafe { std::mem::transmute(r) }; //~ ERROR encountered a pointer, but expected plain (non-pointer) bytes
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// compile-flags: -Zmiri-check-number-validity
2+
3+
fn main() {
4+
let r = &mut 42;
5+
let _i: usize = unsafe { std::mem::transmute(r) }; //~ ERROR expected initialized plain (non-pointer) bytes
6+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// ignore-windows: Concurrency on Windows is not supported yet.
2+
// compile-flags: -Zmiri-disable-isolation
3+
4+
use std::sync::mpsc::{channel, sync_channel};
5+
use std::thread;
6+
7+
// Check if channels are working.
8+
9+
/// The test taken from the Rust documentation.
10+
fn simple_send() {
11+
let (tx, rx) = channel();
12+
thread::spawn(move || {
13+
tx.send(10).unwrap();
14+
});
15+
assert_eq!(rx.recv().unwrap(), 10);
16+
}
17+
18+
/// The test taken from the Rust documentation.
19+
fn multiple_send() {
20+
let (tx, rx) = channel();
21+
for i in 0..10 {
22+
let tx = tx.clone();
23+
thread::spawn(move || {
24+
tx.send(i).unwrap();
25+
});
26+
}
27+
28+
let mut sum = 0;
29+
for _ in 0..10 {
30+
let j = rx.recv().unwrap();
31+
assert!(0 <= j && j < 10);
32+
sum += j;
33+
}
34+
assert_eq!(sum, 45);
35+
}
36+
37+
/// The test taken from the Rust documentation.
38+
fn send_on_sync() {
39+
let (sender, receiver) = sync_channel(1);
40+
41+
// this returns immediately
42+
sender.send(1).unwrap();
43+
44+
thread::spawn(move || {
45+
// this will block until the previous message has been received
46+
sender.send(2).unwrap();
47+
});
48+
49+
assert_eq!(receiver.recv().unwrap(), 1);
50+
assert_eq!(receiver.recv().unwrap(), 2);
51+
}
52+
53+
fn main() {
54+
simple_send();
55+
multiple_send();
56+
send_on_sync();
57+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
warning: thread support is experimental and incomplete: weak memory effects are not emulated.
2+

tests/run-pass/concurrency/simple.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// ignore-windows: Concurrency on Windows is not supported yet.
2+
// compile-flags: -Zmiri-check-number-validity
23

34
use std::thread;
45

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
warning: thread support is experimental and incomplete: weak memory effects are not emulated.
22

3-
thread '<unnamed>' panicked at 'Hello!', $DIR/simple.rs:54:9
3+
thread '<unnamed>' panicked at 'Hello!', $DIR/simple.rs:55:9
44
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
5-
thread 'childthread' panicked at 'Hello, world!', $DIR/simple.rs:64:9
5+
thread 'childthread' panicked at 'Hello, world!', $DIR/simple.rs:65:9

tests/run-pass/concurrency/sync.rs

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// ignore-windows: Concurrency on Windows is not supported yet.
22
// compile-flags: -Zmiri-disable-isolation -Zmiri-check-number-validity
33

4-
use std::sync::mpsc::{channel, sync_channel};
54
use std::sync::{Arc, Barrier, Condvar, Mutex, Once, RwLock};
65
use std::thread;
76
use std::time::{Duration, Instant};
@@ -181,52 +180,6 @@ fn check_rwlock_read_no_deadlock() {
181180
handle.join().unwrap();
182181
}
183182

184-
// Check if channels are working.
185-
186-
/// The test taken from the Rust documentation.
187-
fn simple_send() {
188-
let (tx, rx) = channel();
189-
thread::spawn(move || {
190-
tx.send(10).unwrap();
191-
});
192-
assert_eq!(rx.recv().unwrap(), 10);
193-
}
194-
195-
/// The test taken from the Rust documentation.
196-
fn multiple_send() {
197-
let (tx, rx) = channel();
198-
for i in 0..10 {
199-
let tx = tx.clone();
200-
thread::spawn(move || {
201-
tx.send(i).unwrap();
202-
});
203-
}
204-
205-
let mut sum = 0;
206-
for _ in 0..10 {
207-
let j = rx.recv().unwrap();
208-
assert!(0 <= j && j < 10);
209-
sum += j;
210-
}
211-
assert_eq!(sum, 45);
212-
}
213-
214-
/// The test taken from the Rust documentation.
215-
fn send_on_sync() {
216-
let (sender, receiver) = sync_channel(1);
217-
218-
// this returns immediately
219-
sender.send(1).unwrap();
220-
221-
thread::spawn(move || {
222-
// this will block until the previous message has been received
223-
sender.send(2).unwrap();
224-
});
225-
226-
assert_eq!(receiver.recv().unwrap(), 1);
227-
assert_eq!(receiver.recv().unwrap(), 2);
228-
}
229-
230183
// Check if Rust once statics are working.
231184

232185
static mut VAL: usize = 0;
@@ -353,9 +306,6 @@ fn main() {
353306
check_mutex();
354307
check_rwlock_write();
355308
check_rwlock_read_no_deadlock();
356-
simple_send();
357-
multiple_send();
358-
send_on_sync();
359309
check_once();
360310
check_rwlock_unlock_bug1();
361311
check_rwlock_unlock_bug2();

tests/run-pass/concurrency/thread_locals.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// ignore-windows: Concurrency on Windows is not supported yet.
2+
// compile-flags: -Zmiri-check-number-validity
23

34
//! The main purpose of this test is to check that if we take a pointer to
45
//! thread's `t1` thread-local `A` and send it to another thread `t2`,

0 commit comments

Comments
 (0)