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.
This commit is contained in:
commit
c1bbf078f3
@ -1 +1 @@
|
|||||||
d2df372bca13bb60979c909660e69f2451630e81
|
100f12d17026fccfc5d80527b5976dd66b228b13
|
||||||
|
@ -10,13 +10,14 @@ use std::time::Instant;
|
|||||||
use rand::rngs::StdRng;
|
use rand::rngs::StdRng;
|
||||||
use rand::SeedableRng;
|
use rand::SeedableRng;
|
||||||
|
|
||||||
|
use rustc_ast::ast::Mutability;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_middle::{
|
use rustc_middle::{
|
||||||
mir,
|
mir,
|
||||||
ty::{
|
ty::{
|
||||||
self,
|
self,
|
||||||
layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout},
|
layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout},
|
||||||
Instance, TyCtxt,
|
Instance, TyCtxt, TypeAndMut,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use rustc_span::def_id::{CrateNum, DefId};
|
use rustc_span::def_id::{CrateNum, DefId};
|
||||||
@ -269,19 +270,23 @@ pub struct PrimitiveLayouts<'tcx> {
|
|||||||
pub u32: TyAndLayout<'tcx>,
|
pub u32: TyAndLayout<'tcx>,
|
||||||
pub usize: TyAndLayout<'tcx>,
|
pub usize: TyAndLayout<'tcx>,
|
||||||
pub bool: TyAndLayout<'tcx>,
|
pub bool: TyAndLayout<'tcx>,
|
||||||
|
pub mut_raw_ptr: TyAndLayout<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
|
impl<'mir, 'tcx: 'mir> PrimitiveLayouts<'tcx> {
|
||||||
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, LayoutError<'tcx>> {
|
fn new(layout_cx: LayoutCx<'tcx, TyCtxt<'tcx>>) -> Result<Self, LayoutError<'tcx>> {
|
||||||
|
let tcx = layout_cx.tcx;
|
||||||
|
let mut_raw_ptr = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
unit: layout_cx.layout_of(layout_cx.tcx.mk_unit())?,
|
unit: layout_cx.layout_of(tcx.mk_unit())?,
|
||||||
i8: layout_cx.layout_of(layout_cx.tcx.types.i8)?,
|
i8: layout_cx.layout_of(tcx.types.i8)?,
|
||||||
i32: layout_cx.layout_of(layout_cx.tcx.types.i32)?,
|
i32: layout_cx.layout_of(tcx.types.i32)?,
|
||||||
isize: layout_cx.layout_of(layout_cx.tcx.types.isize)?,
|
isize: layout_cx.layout_of(tcx.types.isize)?,
|
||||||
u8: layout_cx.layout_of(layout_cx.tcx.types.u8)?,
|
u8: layout_cx.layout_of(tcx.types.u8)?,
|
||||||
u32: layout_cx.layout_of(layout_cx.tcx.types.u32)?,
|
u32: layout_cx.layout_of(tcx.types.u32)?,
|
||||||
usize: layout_cx.layout_of(layout_cx.tcx.types.usize)?,
|
usize: layout_cx.layout_of(tcx.types.usize)?,
|
||||||
bool: layout_cx.layout_of(layout_cx.tcx.types.bool)?,
|
bool: layout_cx.layout_of(tcx.types.bool)?,
|
||||||
|
mut_raw_ptr: layout_cx.layout_of(mut_raw_ptr)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::*;
|
use crate::*;
|
||||||
use rustc_ast::ast::Mutability;
|
use rustc_ast::ast::Mutability;
|
||||||
use rustc_middle::ty::layout::LayoutOf as _;
|
use rustc_middle::ty::layout::LayoutOf as _;
|
||||||
use rustc_middle::ty::{self, Instance, TypeAndMut};
|
use rustc_middle::ty::{self, Instance};
|
||||||
use rustc_span::{BytePos, Loc, Symbol};
|
use rustc_span::{BytePos, Loc, Symbol};
|
||||||
use rustc_target::{abi::Size, spec::abi::Abi};
|
use rustc_target::{abi::Size, spec::abi::Abi};
|
||||||
use std::convert::TryInto as _;
|
use std::convert::TryInto as _;
|
||||||
@ -71,8 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||||||
|
|
||||||
let len: u64 = ptrs.len().try_into().unwrap();
|
let len: u64 = ptrs.len().try_into().unwrap();
|
||||||
|
|
||||||
let ptr_ty = tcx.mk_ptr(TypeAndMut { ty: tcx.types.unit, mutbl: Mutability::Mut });
|
let ptr_ty = this.machine.layouts.mut_raw_ptr.ty;
|
||||||
|
|
||||||
let array_layout = this.layout_of(tcx.mk_array(ptr_ty, len)).unwrap();
|
let array_layout = this.layout_of(tcx.mk_array(ptr_ty, len)).unwrap();
|
||||||
|
|
||||||
match flags {
|
match flags {
|
||||||
|
@ -440,7 +440,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||||||
} else {
|
} else {
|
||||||
// No `environ` allocated yet, let's do that.
|
// No `environ` allocated yet, let's do that.
|
||||||
// This is memory backing an extern static, hence `ExternStatic`, not `Env`.
|
// This is memory backing an extern static, hence `ExternStatic`, not `Env`.
|
||||||
let layout = this.machine.layouts.usize;
|
let layout = this.machine.layouts.mut_raw_ptr;
|
||||||
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
|
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
|
||||||
this.machine.env_vars.environ = Some(place);
|
this.machine.env_vars.environ = Some(place);
|
||||||
}
|
}
|
||||||
@ -452,8 +452,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||||||
vars.push(Pointer::null());
|
vars.push(Pointer::null());
|
||||||
// Make an array with all these pointers inside Miri.
|
// Make an array with all these pointers inside Miri.
|
||||||
let tcx = this.tcx;
|
let tcx = this.tcx;
|
||||||
let vars_layout =
|
let vars_layout = this.layout_of(
|
||||||
this.layout_of(tcx.mk_array(tcx.types.usize, u64::try_from(vars.len()).unwrap()))?;
|
tcx.mk_array(this.machine.layouts.mut_raw_ptr.ty, u64::try_from(vars.len()).unwrap()),
|
||||||
|
)?;
|
||||||
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Runtime.into())?;
|
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Runtime.into())?;
|
||||||
for (idx, var) in vars.into_iter().enumerate() {
|
for (idx, var) in vars.into_iter().enumerate() {
|
||||||
let place = this.mplace_field(&vars_place, idx)?;
|
let place = this.mplace_field(&vars_place, idx)?;
|
||||||
|
6
tests/compile-fail/ptr_integer_array_transmute.rs
Normal file
6
tests/compile-fail/ptr_integer_array_transmute.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// compile-flags: -Zmiri-check-number-validity
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let r = &mut 42;
|
||||||
|
let _i: [usize; 1] = unsafe { std::mem::transmute(r) }; //~ ERROR encountered a pointer, but expected plain (non-pointer) bytes
|
||||||
|
}
|
6
tests/compile-fail/ptr_integer_transmute.rs
Normal file
6
tests/compile-fail/ptr_integer_transmute.rs
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// compile-flags: -Zmiri-check-number-validity
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let r = &mut 42;
|
||||||
|
let _i: usize = unsafe { std::mem::transmute(r) }; //~ ERROR expected initialized plain (non-pointer) bytes
|
||||||
|
}
|
57
tests/run-pass/concurrency/channels.rs
Normal file
57
tests/run-pass/concurrency/channels.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// ignore-windows: Concurrency on Windows is not supported yet.
|
||||||
|
// compile-flags: -Zmiri-disable-isolation
|
||||||
|
|
||||||
|
use std::sync::mpsc::{channel, sync_channel};
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
// Check if channels are working.
|
||||||
|
|
||||||
|
/// The test taken from the Rust documentation.
|
||||||
|
fn simple_send() {
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
thread::spawn(move || {
|
||||||
|
tx.send(10).unwrap();
|
||||||
|
});
|
||||||
|
assert_eq!(rx.recv().unwrap(), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The test taken from the Rust documentation.
|
||||||
|
fn multiple_send() {
|
||||||
|
let (tx, rx) = channel();
|
||||||
|
for i in 0..10 {
|
||||||
|
let tx = tx.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
tx.send(i).unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut sum = 0;
|
||||||
|
for _ in 0..10 {
|
||||||
|
let j = rx.recv().unwrap();
|
||||||
|
assert!(0 <= j && j < 10);
|
||||||
|
sum += j;
|
||||||
|
}
|
||||||
|
assert_eq!(sum, 45);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The test taken from the Rust documentation.
|
||||||
|
fn send_on_sync() {
|
||||||
|
let (sender, receiver) = sync_channel(1);
|
||||||
|
|
||||||
|
// this returns immediately
|
||||||
|
sender.send(1).unwrap();
|
||||||
|
|
||||||
|
thread::spawn(move || {
|
||||||
|
// this will block until the previous message has been received
|
||||||
|
sender.send(2).unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(receiver.recv().unwrap(), 1);
|
||||||
|
assert_eq!(receiver.recv().unwrap(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
simple_send();
|
||||||
|
multiple_send();
|
||||||
|
send_on_sync();
|
||||||
|
}
|
2
tests/run-pass/concurrency/channels.stderr
Normal file
2
tests/run-pass/concurrency/channels.stderr
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
warning: thread support is experimental and incomplete: weak memory effects are not emulated.
|
||||||
|
|
@ -1,4 +1,5 @@
|
|||||||
// ignore-windows: Concurrency on Windows is not supported yet.
|
// ignore-windows: Concurrency on Windows is not supported yet.
|
||||||
|
// compile-flags: -Zmiri-check-number-validity
|
||||||
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
warning: thread support is experimental and incomplete: weak memory effects are not emulated.
|
warning: thread support is experimental and incomplete: weak memory effects are not emulated.
|
||||||
|
|
||||||
thread '<unnamed>' panicked at 'Hello!', $DIR/simple.rs:54:9
|
thread '<unnamed>' panicked at 'Hello!', $DIR/simple.rs:55:9
|
||||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
|
||||||
thread 'childthread' panicked at 'Hello, world!', $DIR/simple.rs:64:9
|
thread 'childthread' panicked at 'Hello, world!', $DIR/simple.rs:65:9
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// ignore-windows: Concurrency on Windows is not supported yet.
|
// ignore-windows: Concurrency on Windows is not supported yet.
|
||||||
// compile-flags: -Zmiri-disable-isolation -Zmiri-check-number-validity
|
// compile-flags: -Zmiri-disable-isolation -Zmiri-check-number-validity
|
||||||
|
|
||||||
use std::sync::mpsc::{channel, sync_channel};
|
|
||||||
use std::sync::{Arc, Barrier, Condvar, Mutex, Once, RwLock};
|
use std::sync::{Arc, Barrier, Condvar, Mutex, Once, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
@ -181,52 +180,6 @@ fn check_rwlock_read_no_deadlock() {
|
|||||||
handle.join().unwrap();
|
handle.join().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if channels are working.
|
|
||||||
|
|
||||||
/// The test taken from the Rust documentation.
|
|
||||||
fn simple_send() {
|
|
||||||
let (tx, rx) = channel();
|
|
||||||
thread::spawn(move || {
|
|
||||||
tx.send(10).unwrap();
|
|
||||||
});
|
|
||||||
assert_eq!(rx.recv().unwrap(), 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The test taken from the Rust documentation.
|
|
||||||
fn multiple_send() {
|
|
||||||
let (tx, rx) = channel();
|
|
||||||
for i in 0..10 {
|
|
||||||
let tx = tx.clone();
|
|
||||||
thread::spawn(move || {
|
|
||||||
tx.send(i).unwrap();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut sum = 0;
|
|
||||||
for _ in 0..10 {
|
|
||||||
let j = rx.recv().unwrap();
|
|
||||||
assert!(0 <= j && j < 10);
|
|
||||||
sum += j;
|
|
||||||
}
|
|
||||||
assert_eq!(sum, 45);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The test taken from the Rust documentation.
|
|
||||||
fn send_on_sync() {
|
|
||||||
let (sender, receiver) = sync_channel(1);
|
|
||||||
|
|
||||||
// this returns immediately
|
|
||||||
sender.send(1).unwrap();
|
|
||||||
|
|
||||||
thread::spawn(move || {
|
|
||||||
// this will block until the previous message has been received
|
|
||||||
sender.send(2).unwrap();
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(receiver.recv().unwrap(), 1);
|
|
||||||
assert_eq!(receiver.recv().unwrap(), 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if Rust once statics are working.
|
// Check if Rust once statics are working.
|
||||||
|
|
||||||
static mut VAL: usize = 0;
|
static mut VAL: usize = 0;
|
||||||
@ -353,9 +306,6 @@ fn main() {
|
|||||||
check_mutex();
|
check_mutex();
|
||||||
check_rwlock_write();
|
check_rwlock_write();
|
||||||
check_rwlock_read_no_deadlock();
|
check_rwlock_read_no_deadlock();
|
||||||
simple_send();
|
|
||||||
multiple_send();
|
|
||||||
send_on_sync();
|
|
||||||
check_once();
|
check_once();
|
||||||
check_rwlock_unlock_bug1();
|
check_rwlock_unlock_bug1();
|
||||||
check_rwlock_unlock_bug2();
|
check_rwlock_unlock_bug2();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
// ignore-windows: Concurrency on Windows is not supported yet.
|
// ignore-windows: Concurrency on Windows is not supported yet.
|
||||||
|
// compile-flags: -Zmiri-check-number-validity
|
||||||
|
|
||||||
//! The main purpose of this test is to check that if we take a pointer to
|
//! The main purpose of this test is to check that if we take a pointer to
|
||||||
//! thread's `t1` thread-local `A` and send it to another thread `t2`,
|
//! thread's `t1` thread-local `A` and send it to another thread `t2`,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user