diff --git a/Cargo.lock b/Cargo.lock index 8d80f1f11cd..d3b6ee0bb53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -215,6 +215,11 @@ dependencies = [ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "env_logger" version = "0.6.2" @@ -294,6 +299,14 @@ dependencies = [ "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "itertools" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "itoa" version = "0.4.4" @@ -343,6 +356,7 @@ dependencies = [ "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", "getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -828,6 +842,7 @@ dependencies = [ "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a" "checksum directories 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" "checksum dirs-sys 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "afa0b23de8fd801745c471deffa6e12d248f962c9fd4b4c33787b055599bde7b" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" "checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" @@ -837,6 +852,7 @@ dependencies = [ "checksum getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fc344b02d3868feb131e8b5fe2b9b0a1cc42942679af493061fc13b853243872" "checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" +"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" diff --git a/Cargo.toml b/Cargo.toml index bd345ea2b7f..91da02eac8a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ log = "0.4" shell-escape = "0.1.4" hex = "0.3.2" rand = "0.7" +itertools = "0.8" # A noop dependency that changes in the Rust repository, it's a bit of a hack. # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` diff --git a/rust-version b/rust-version index 8e2cace3385..b2b3a89fe95 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -7979016aff545f7b41cc517031026020b340989d +6576f4be5af31a5e61dfc0cf50b7130e6c6dfb35 diff --git a/src/eval.rs b/src/eval.rs index f4a8d176172..13396e845da 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -257,8 +257,9 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) { trace!("-------------------"); trace!("Frame {}", i); trace!(" return: {:?}", frame.return_place.map(|p| *p)); - for (i, local) in frame.locals.iter().enumerate() { - trace!(" local {}: {:?}", i, local.value); + for (_i, _local) in frame.locals.iter().enumerate() { + //trace!(" local {}: {:?}", i, local.value); + //FIXME: enable this again when the LocalValue Debug impl is back } } } diff --git a/src/helpers.rs b/src/helpers.rs index 16091bb242c..9e1fa343705 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -4,7 +4,7 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX}; use rustc::mir; use rustc::ty::{ self, - layout::{self, Align, LayoutOf, Size, TyLayout}, + layout::{self, LayoutOf, Size, TyLayout}, }; use rand::RngCore; @@ -94,13 +94,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } let this = self.eval_context_mut(); - // Don't forget the bounds check. - let ptr = this.memory.check_ptr_access( - ptr, - Size::from_bytes(len as u64), - Align::from_bytes(1).unwrap() - )?.expect("we already checked for size 0"); - let mut data = vec![0; len]; if this.machine.communicate { @@ -113,7 +106,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx rng.fill_bytes(&mut data); } - this.memory.get_mut(ptr.alloc_id)?.write_bytes(&*this.tcx, ptr, &data) + this.memory.write_bytes(ptr, data.iter().copied()) } /// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter diff --git a/src/shims/env.rs b/src/shims/env.rs index 661e8bf209b..28f1c7d2ef9 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -122,7 +122,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx this.check_no_isolation("getcwd")?; - let buf = this.force_ptr(this.read_scalar(buf_op)?.not_undef()?)?; + let buf = this.read_scalar(buf_op)?.not_undef()?; let size = this.read_scalar(size_op)?.to_usize(&*this.tcx)?; // If we cannot get the current directory, we return null match env::current_dir() { @@ -138,10 +138,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx // This is ok because the buffer was strictly larger than `bytes`, so after // adding the null terminator, the buffer size is larger or equal to // `bytes.len()`, meaning that `bytes` actually fit inside tbe buffer. - this.memory - .get_mut(buf.alloc_id)? - .write_bytes(&*this.tcx, buf, &bytes)?; - return Ok(Scalar::Ptr(buf)); + this.memory.write_bytes(buf, bytes.iter().copied())?; + return Ok(buf); } let erange = this.eval_libc("ERANGE")?; this.set_last_error(erange)?; diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 1933aee1151..66fb53581e6 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -52,9 +52,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx if zero_init { // We just allocated this, the access is definitely in-bounds. this.memory - .get_mut(ptr.alloc_id) - .unwrap() - .write_repeat(&*this.tcx, ptr, 0, Size::from_bytes(size)) + .write_bytes(ptr.into(), itertools::repeat_n(0u8, size as usize)) .unwrap(); } Scalar::Ptr(ptr) @@ -229,9 +227,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx ); // We just allocated this, the access is definitely in-bounds. this.memory - .get_mut(ptr.alloc_id) - .unwrap() - .write_repeat(tcx, ptr, 0, Size::from_bytes(size)) + .write_bytes(ptr.into(), itertools::repeat_n(0u8, size as usize)) .unwrap(); this.write_scalar(Scalar::Ptr(ptr), dest)?; } @@ -841,25 +837,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } "GetSystemInfo" => { let system_info = this.deref_operand(args[0])?; - let system_info_ptr = this - .check_mplace_access(system_info, None)? - .expect("cannot be a ZST"); - // We rely on `deref_operand` doing bounds checks for us. // Initialize with `0`. this.memory - .get_mut(system_info_ptr.alloc_id)? - .write_repeat(tcx, system_info_ptr, 0, system_info.layout.size)?; + .write_bytes(system_info.ptr, itertools::repeat_n(0, system_info.layout.size.bytes() as usize))?; // Set number of processors. let dword_size = Size::from_bytes(4); - let offset = 2 * dword_size + 3 * tcx.pointer_size(); - this.memory - .get_mut(system_info_ptr.alloc_id)? - .write_scalar( - tcx, - system_info_ptr.offset(offset, tcx)?, - Scalar::from_int(NUM_CPUS, dword_size).into(), - dword_size, - )?; + let num_cpus = this.mplace_field(system_info, 6)?; + this.write_scalar( + Scalar::from_int(NUM_CPUS, dword_size), + num_cpus.into(), + )?; } "TlsAlloc" => { diff --git a/src/shims/intrinsics.rs b/src/shims/intrinsics.rs index 46658760cc1..d39e70d8990 100644 --- a/src/shims/intrinsics.rs +++ b/src/shims/intrinsics.rs @@ -356,11 +356,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx _ => { // Do it in memory let mplace = this.force_allocation(dest)?; - mplace.meta.unwrap_none(); - // not a zst, must be valid pointer - let ptr = mplace.ptr.to_ptr()?; - // we know the return place is in-bounds - this.memory.get_mut(ptr.alloc_id)?.write_repeat(tcx, ptr, 0, dest.layout.size)?; + mplace.meta.unwrap_none(); // must be sized + this.memory.write_bytes(mplace.ptr, itertools::repeat_n(0, dest.layout.size.bytes() as usize))?; } } } @@ -565,16 +562,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx let ptr = this.read_scalar(args[0])?.not_undef()?; let count = this.read_scalar(args[2])?.to_usize(this)?; let byte_count = ty_layout.size * count; - match this.memory.check_ptr_access(ptr, byte_count, ty_layout.align.abi)? { - Some(ptr) => { - this.memory - .get_mut(ptr.alloc_id)? - .write_repeat(tcx, ptr, val_byte, byte_count)?; - } - None => { - // Size is 0, nothing to do. - } - } + this.memory.write_bytes(ptr, itertools::repeat_n(val_byte, byte_count.bytes() as usize))?; } name => throw_unsup_format!("unimplemented intrinsic: {}", name), diff --git a/tests/run-pass/union-overwrite.rs b/tests/run-pass/union-overwrite.rs index 5c618763c0d..d3c81834bc4 100644 --- a/tests/run-pass/union-overwrite.rs +++ b/tests/run-pass/union-overwrite.rs @@ -1,19 +1,20 @@ #![feature(untagged_unions)] -#![allow(unions_with_drop_fields)] #[repr(C)] +#[derive(Clone, Copy)] struct Pair(T, U); #[repr(C)] +#[derive(Clone, Copy)] struct Triple(T, T, T); #[repr(C)] -union U { +union U { a: Pair, b: B, } #[repr(C)] -union W { +union W { a: A, b: B, }