diff --git a/rust-version b/rust-version index e278a80633..e70f05a009 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -481068a707679257e2a738b40987246e0420e787 +b820c761744db080ff7a4ba3ac88d259065cb836 diff --git a/src/eval.rs b/src/eval.rs index 6132c50253..bf99d3e611 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -11,7 +11,7 @@ use rustc::mir; use crate::{ InterpResult, InterpError, InterpCx, StackPopCleanup, struct_error, - Scalar, Tag, Pointer, + Scalar, Tag, Pointer, FnVal, MemoryExtra, MiriMemoryKind, Evaluator, TlsEvalContextExt, }; @@ -93,7 +93,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( let mut args = ecx.frame().body.args_iter(); // First argument: pointer to `main()`. - let main_ptr = ecx.memory_mut().create_fn_alloc(main_instance); + let main_ptr = ecx.memory_mut().create_fn_alloc(FnVal::Instance(main_instance)); let dest = ecx.eval_place(&mir::Place::Base(mir::PlaceBase::Local(args.next().unwrap())))?; ecx.write_scalar(Scalar::Ptr(main_ptr), dest)?; diff --git a/src/helpers.rs b/src/helpers.rs index 3503af4369..b9fa7bc2a7 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -1,8 +1,10 @@ use std::mem; -use rustc::ty::{self, layout::{self, Size}}; +use rustc::ty::{self, layout::{self, Size, Align}}; use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX}; +use rand::RngCore; + use crate::*; impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} @@ -65,6 +67,40 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx }) } + /// Generate some random bytes, and write them to `dest`. + fn gen_random( + &mut self, + len: usize, + ptr: Scalar, + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + + let ptr = match this.memory().check_ptr_access(ptr, Size::from_bytes(len as u64), Align::from_bytes(1).unwrap())? { + Some(ptr) => ptr, + None => return Ok(()), // zero-sized access + }; + + let data = match &mut this.memory_mut().extra.rng { + Some(rng) => { + let mut rng = rng.borrow_mut(); + let mut data = vec![0; len]; + rng.fill_bytes(&mut data); + data + } + None => { + return err!(Unimplemented( + "miri does not support gathering system entropy in deterministic mode! + Use '-Zmiri-seed=' to enable random number generation. + WARNING: Miri does *not* generate cryptographically secure entropy - + do not use Miri to run any program that needs secure random number generation".to_owned(), + )); + } + }; + let tcx = &{this.tcx.tcx}; + this.memory_mut().get_mut(ptr.alloc_id)? + .write_bytes(tcx, ptr, &data) + } + /// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter /// will be true if this is frozen, false if this is in an `UnsafeCell`. fn visit_freeze_sensitive( diff --git a/src/lib.rs b/src/lib.rs index 31e7070777..20c24ad54f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,13 +31,14 @@ pub use crate::shims::{EvalContextExt as ShimsEvalContextExt}; pub use crate::shims::foreign_items::EvalContextExt as ForeignItemsEvalContextExt; pub use crate::shims::intrinsics::EvalContextExt as IntrinsicsEvalContextExt; pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData}; +pub use crate::shims::dlsym::{Dlsym, EvalContextExt as DlsymEvalContextExt}; pub use crate::operator::EvalContextExt as OperatorEvalContextExt; pub use crate::range_map::RangeMap; pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt}; pub use crate::mono_hash_map::MonoHashMap; pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item}; pub use crate::machine::{ - PAGE_SIZE, STACK_ADDR, NUM_CPUS, + PAGE_SIZE, STACK_ADDR, STACK_SIZE, NUM_CPUS, MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt, }; pub use crate::eval::{eval_main, create_ecx, MiriConfig}; diff --git a/src/machine.rs b/src/machine.rs index 0875331131..d1cf913a75 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -11,14 +11,15 @@ use rand::rngs::StdRng; use syntax::attr; use syntax::symbol::sym; use rustc::hir::def_id::DefId; -use rustc::ty::{self, layout::{Size, LayoutOf}, query::TyCtxtAt}; +use rustc::ty::{self, layout::{Size, LayoutOf}, TyCtxt}; use rustc::mir; use crate::*; // Some global facts about the emulated machine. pub const PAGE_SIZE: u64 = 4*1024; // FIXME: adjust to target architecture -pub const STACK_ADDR: u64 = 16*PAGE_SIZE; // not really about the "stack", but where we start assigning integer addresses to allocations +pub const STACK_ADDR: u64 = 32*PAGE_SIZE; // not really about the "stack", but where we start assigning integer addresses to allocations +pub const STACK_SIZE: u64 = 16*PAGE_SIZE; // whatever pub const NUM_CPUS: u64 = 1; /// Extra memory kinds @@ -135,6 +136,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { type MemoryExtra = MemoryExtra; type AllocExtra = AllocExtra; type PointerTag = Tag; + type ExtraFnVal = Dlsym; type MemoryMap = MonoHashMap, Allocation)>; @@ -145,7 +147,6 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { ecx.memory().extra.validate } - /// Returns `Ok()` when the function was handled; fail otherwise. #[inline(always)] fn find_fn( ecx: &mut InterpCx<'mir, 'tcx, Self>, @@ -157,6 +158,17 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { ecx.find_fn(instance, args, dest, ret) } + #[inline(always)] + fn call_extra_fn( + ecx: &mut InterpCx<'mir, 'tcx, Self>, + fn_val: Dlsym, + args: &[OpTy<'tcx, Tag>], + dest: Option>, + ret: Option, + ) -> InterpResult<'tcx> { + ecx.call_dlsym(fn_val, args, dest, ret) + } + #[inline(always)] fn call_intrinsic( ecx: &mut rustc_mir::interpret::InterpCx<'mir, 'tcx, Self>, @@ -220,8 +232,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { } fn find_foreign_static( + tcx: TyCtxt<'tcx>, def_id: DefId, - tcx: TyCtxtAt<'tcx>, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>> { let attrs = tcx.get_attrs(def_id); let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) { @@ -251,20 +263,20 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { } fn tag_allocation<'b>( + memory_extra: &MemoryExtra, id: AllocId, alloc: Cow<'b, Allocation>, kind: Option>, - memory: &Memory<'mir, 'tcx, Self>, ) -> (Cow<'b, Allocation>, Self::PointerTag) { let kind = kind.expect("we set our STATIC_KIND so this cannot be None"); let alloc = alloc.into_owned(); - let (stacks, base_tag) = if !memory.extra.validate { + let (stacks, base_tag) = if !memory_extra.validate { (None, Tag::Untagged) } else { let (stacks, base_tag) = Stacks::new_allocation( id, Size::from_bytes(alloc.bytes.len() as u64), - Rc::clone(&memory.extra.stacked_borrows), + Rc::clone(&memory_extra.stacked_borrows), kind, ); (Some(stacks), base_tag) @@ -273,7 +285,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { assert!(alloc.relocations.is_empty(), "Only statics can come initialized with inner pointers"); // Now we can rely on the inner pointers being static, too. } - let mut memory_extra = memory.extra.stacked_borrows.borrow_mut(); + let mut stacked_borrows = memory_extra.stacked_borrows.borrow_mut(); let alloc: Allocation = Allocation { bytes: alloc.bytes, relocations: Relocations::from_presorted( @@ -281,10 +293,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { // The allocations in the relocations (pointers stored *inside* this allocation) // all get the base pointer tag. .map(|&(offset, ((), alloc))| { - let tag = if !memory.extra.validate { + let tag = if !memory_extra.validate { Tag::Untagged } else { - memory_extra.static_base_ptr(alloc) + stacked_borrows.static_base_ptr(alloc) }; (offset, (tag, alloc)) }) @@ -302,13 +314,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { #[inline(always)] fn tag_static_base_pointer( + memory_extra: &MemoryExtra, id: AllocId, - memory: &Memory<'mir, 'tcx, Self>, ) -> Self::PointerTag { - if !memory.extra.validate { + if !memory_extra.validate { Tag::Untagged } else { - memory.extra.stacked_borrows.borrow_mut().static_base_ptr(id) + memory_extra.stacked_borrows.borrow_mut().static_base_ptr(id) } } @@ -342,8 +354,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { } fn int_to_ptr( - int: u64, memory: &Memory<'mir, 'tcx, Self>, + int: u64, ) -> InterpResult<'tcx, Pointer> { if int == 0 { err!(InvalidNullPointerUsage) @@ -355,8 +367,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> { } fn ptr_to_int( - ptr: Pointer, memory: &Memory<'mir, 'tcx, Self>, + ptr: Pointer, ) -> InterpResult<'tcx, u64> { if memory.extra.rng.is_none() { err!(ReadPointerAsBytes) diff --git a/src/shims/dlsym.rs b/src/shims/dlsym.rs new file mode 100644 index 0000000000..602d8064e8 --- /dev/null +++ b/src/shims/dlsym.rs @@ -0,0 +1,55 @@ +use rustc::mir; + +use crate::*; + +#[derive(Debug, Copy, Clone)] +pub enum Dlsym { + GetEntropy, +} + +impl Dlsym { + // Returns an error for unsupported symbols, and None if this symbol + // should become a NULL pointer (pretend it does not exist). + pub fn from_str(name: &str) -> InterpResult<'static, Option> { + use self::Dlsym::*; + Ok(match name { + "getentropy" => Some(GetEntropy), + "__pthread_get_minstack" => None, + _ => + return err!(Unimplemented(format!( + "Unsupported dlsym: {}", name + ))), + }) + } +} + +impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} +pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> { + fn call_dlsym( + &mut self, + dlsym: Dlsym, + args: &[OpTy<'tcx, Tag>], + dest: Option>, + ret: Option, + ) -> InterpResult<'tcx> { + use self::Dlsym::*; + + let this = self.eval_context_mut(); + + let dest = dest.expect("we don't support any diverging dlsym"); + let ret = ret.expect("dest is `Some` but ret is `None`"); + + match dlsym { + GetEntropy => { + let ptr = this.read_scalar(args[0])?.not_undef()?; + let len = this.read_scalar(args[1])?.to_usize(this)?; + this.gen_random(len as usize, ptr)?; + this.write_null(dest)?; + } + } + + this.goto_block(Some(ret))?; + this.dump_place(*dest); + Ok(()) + } +} diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 2fe2ecc195..9dbb55668e 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -4,8 +4,6 @@ use rustc::mir; use syntax::attr; use syntax::symbol::sym; -use rand::RngCore; - use crate::*; impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} @@ -307,7 +305,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // neither of which have any effect on our current PRNG let _flags = this.read_scalar(args[3])?.to_i32()?; - gen_random(this, len as usize, ptr)?; + this.gen_random(len as usize, ptr)?; this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?; } id => { @@ -324,10 +322,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let symbol_name = this.memory().get(symbol.alloc_id)?.read_c_str(tcx, symbol)?; let err = format!("bad c unicode symbol: {:?}", symbol_name); let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err); - return err!(Unimplemented(format!( - "miri does not support dynamically loading libraries (requested symbol: {})", - symbol_name - ))); + if let Some(dlsym) = Dlsym::from_str(symbol_name)? { + let ptr = this.memory_mut().create_fn_alloc(FnVal::Other(dlsym)); + this.write_scalar(Scalar::from(ptr), dest)?; + } else { + this.write_null(dest)?; + } } "__rust_maybe_catch_panic" => { @@ -338,9 +338,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // vtable_ptr: *mut usize, // ) -> u32 // We abort on panic, so not much is going on here, but we still have to call the closure. - let f = this.read_scalar(args[0])?.to_ptr()?; + let f = this.read_scalar(args[0])?.not_undef()?; let data = this.read_scalar(args[1])?.not_undef()?; - let f_instance = this.memory().get_fn(f)?; + let f_instance = this.memory().get_fn(f)?.as_instance()?; this.write_null(dest)?; trace!("__rust_maybe_catch_panic: {:?}", f_instance); @@ -659,7 +659,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // Extract the function type out of the signature (that seems easier than constructing it ourselves). let dtor = match this.test_null(this.read_scalar(args[1])?.not_undef()?)? { - Some(dtor_ptr) => Some(this.memory().get_fn(dtor_ptr.to_ptr()?)?), + Some(dtor_ptr) => Some(this.memory().get_fn(dtor_ptr)?.as_instance()?), None => None, }; @@ -709,24 +709,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx this.write_null(dest)?; } - // Determine stack base address. - "pthread_attr_init" | "pthread_attr_destroy" | "pthread_attr_get_np" | - "pthread_getattr_np" | "pthread_self" | "pthread_get_stacksize_np" => { + // Stack size/address stuff. + "pthread_attr_init" | "pthread_attr_destroy" | "pthread_self" | + "pthread_attr_setstacksize" => { this.write_null(dest)?; } "pthread_attr_getstack" => { - // Second argument is where we are supposed to write the stack size. - let ptr = this.deref_operand(args[1])?; - // Just any address. - let stack_addr = Scalar::from_uint(STACK_ADDR, args[1].layout.size); - this.write_scalar(stack_addr, ptr.into())?; + let addr_place = this.deref_operand(args[1])?; + let size_place = this.deref_operand(args[2])?; + + this.write_scalar( + Scalar::from_uint(STACK_ADDR, addr_place.layout.size), + addr_place.into(), + )?; + this.write_scalar( + Scalar::from_uint(STACK_SIZE, size_place.layout.size), + size_place.into(), + )?; + // Return success (`0`). this.write_null(dest)?; } - "pthread_get_stackaddr_np" => { - // Just any address. - let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size); - this.write_scalar(stack_addr, dest)?; + + // We don't support threading. + "pthread_create" => { + return err!(Unimplemented(format!("Miri does not support threading"))); } // Stub out calls for condvar, mutex and rwlock, to just return `0`. @@ -754,6 +761,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } // macOS API stubs. + "pthread_attr_get_np" | "pthread_getattr_np" => { + this.write_null(dest)?; + } + "pthread_get_stackaddr_np" => { + let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size); + this.write_scalar(stack_addr, dest)?; + } + "pthread_get_stacksize_np" => { + let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size); + this.write_scalar(stack_size, dest)?; + } "_tlv_atexit" => { // FIXME: register the destructor. }, @@ -766,7 +784,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "SecRandomCopyBytes" => { let len = this.read_scalar(args[1])?.to_usize(this)?; let ptr = this.read_scalar(args[2])?.not_undef()?; - gen_random(this, len as usize, ptr)?; + this.gen_random(len as usize, ptr)?; this.write_null(dest)?; } @@ -934,7 +952,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx "SystemFunction036" => { let ptr = this.read_scalar(args[0])?.not_undef()?; let len = this.read_scalar(args[1])?.to_u32()?; - gen_random(this, len as usize, ptr)?; + this.gen_random(len as usize, ptr)?; this.write_scalar(Scalar::from_bool(true), dest)?; } @@ -966,36 +984,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } return Ok(None); } -} - -fn gen_random<'mir, 'tcx>( - this: &mut MiriEvalContext<'mir, 'tcx>, - len: usize, - dest: Scalar, -) -> InterpResult<'tcx> { - if len == 0 { - // Nothing to do - return Ok(()); - } - let ptr = dest.to_ptr()?; - - let data = match &mut this.memory_mut().extra.rng { - Some(rng) => { - let mut rng = rng.borrow_mut(); - let mut data = vec![0; len]; - rng.fill_bytes(&mut data); - data - } - None => { - return err!(Unimplemented( - "miri does not support gathering system entropy in deterministic mode! - Use '-Zmiri-seed=' to enable random number generation. - WARNING: Miri does *not* generate cryptographically secure entropy - - do not use Miri to run any program that needs secure random number generation".to_owned(), - )); - } - }; - let tcx = &{this.tcx.tcx}; - this.memory_mut().get_mut(ptr.alloc_id)? - .write_bytes(tcx, ptr, &data) -} +} \ No newline at end of file diff --git a/src/shims/mod.rs b/src/shims/mod.rs index 3258cf3d9c..c06373005f 100644 --- a/src/shims/mod.rs +++ b/src/shims/mod.rs @@ -1,6 +1,7 @@ pub mod foreign_items; pub mod intrinsics; pub mod tls; +pub mod dlsym; use rustc::{ty, mir}; diff --git a/test-cargo-miri/Cargo.lock b/test-cargo-miri/Cargo.lock index 8343832886..55e5a3dfc1 100644 --- a/test-cargo-miri/Cargo.lock +++ b/test-cargo-miri/Cargo.lock @@ -5,11 +5,6 @@ name = "autocfg" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -[[package]] -name = "bitflags" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "byteorder" version = "1.3.2" @@ -33,34 +28,22 @@ dependencies = [ "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - [[package]] name = "getrandom" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "lazy_static" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", +] [[package]] name = "libc" @@ -85,7 +68,7 @@ name = "rand" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -108,7 +91,7 @@ name = "rand_core" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "getrandom 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -129,32 +112,15 @@ dependencies = [ ] [[package]] -name = "winapi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "spin" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" -"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum getrandom 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8d1dffef07351aafe6ef177e4dd2b8dcf503e6bc765dea3b0de9ed149a3db1ec" +"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55" "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" "checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319" "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273" @@ -164,6 +130,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" "checksum rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e196346cbbc5c70c77e7b4926147ee8e383a38ee4d15d58a08098b169e492b6" -"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55" diff --git a/tests/compile-fail/thread-spawn.rs b/tests/compile-fail/thread-spawn.rs new file mode 100644 index 0000000000..450dea99f5 --- /dev/null +++ b/tests/compile-fail/thread-spawn.rs @@ -0,0 +1,7 @@ +use std::thread; + +// error-pattern: Miri does not support threading + +fn main() { + thread::spawn(|| {}); +}