Skip to content

Commit be415db

Browse files
committed
Use new write_bytes method
2 parents 72bd25d + 8fa7454 commit be415db

File tree

10 files changed

+48
-70
lines changed

10 files changed

+48
-70
lines changed

.appveyor.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ branches:
1212
- auto
1313
- try
1414

15+
matrix:
16+
fast_finish: true # set this flag to immediately finish build once one of the jobs fails.
17+
1518
cache:
1619
- '%USERPROFILE%\.cargo'
1720
- '%USERPROFILE%\.rustup'

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ log = "0.4"
4040
shell-escape = "0.1.4"
4141
hex = "0.3.2"
4242
rand = "0.7"
43+
itertools = "0.8"
4344

4445
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
4546
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7979016aff545f7b41cc517031026020b340989d
1+
6576f4be5af31a5e61dfc0cf50b7130e6c6dfb35

src/eval.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,9 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) {
257257
trace!("-------------------");
258258
trace!("Frame {}", i);
259259
trace!(" return: {:?}", frame.return_place.map(|p| *p));
260-
for (i, local) in frame.locals.iter().enumerate() {
261-
trace!(" local {}: {:?}", i, local.value);
260+
for (_i, _local) in frame.locals.iter().enumerate() {
261+
//trace!(" local {}: {:?}", i, local.value);
262+
//FIXME: enable this again when the LocalValue Debug impl is back
262263
}
263264
}
264265
}

src/helpers.rs

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
55
use rustc::mir;
66
use rustc::ty::{
77
self,
8-
layout::{self, Align, LayoutOf, Size, TyLayout},
8+
layout::{self, LayoutOf, Size, TyLayout},
99
};
1010

1111
use rand::RngCore;
@@ -95,13 +95,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9595
}
9696
let this = self.eval_context_mut();
9797

98-
// Don't forget the bounds check.
99-
let ptr = this.memory.check_ptr_access(
100-
ptr,
101-
Size::from_bytes(len as u64),
102-
Align::from_bytes(1).unwrap()
103-
)?.expect("we already checked for size 0");
104-
10598
let mut data = vec![0; len];
10699

107100
if this.machine.communicate {
@@ -114,7 +107,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
114107
rng.fill_bytes(&mut data);
115108
}
116109

117-
this.memory.get_mut(ptr.alloc_id)?.write_bytes(&*this.tcx, ptr, &data)
110+
this.memory.write_bytes(ptr, data.iter().copied())
118111
}
119112

120113
/// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter
@@ -420,27 +413,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
420413

421414
/// Helper function to write an OsStr as a null-terminated sequence of bytes, which is what
422415
/// the Unix APIs usually handle.
423-
fn write_os_str_to_c_string(&mut self, os_str: &OsStr, ptr: Pointer<Tag>, size: u64) -> InterpResult<'tcx> {
416+
fn write_os_str_to_c_string(&mut self, os_str: &OsStr, scalar: Scalar<Tag>, size: u64) -> InterpResult<'tcx> {
424417
let bytes = os_str_to_bytes(os_str)?;
425-
let len = bytes.len();
426418
// If `size` is smaller or equal than `bytes.len()`, writing `bytes` plus the required null
427419
// terminator to memory using the `ptr` pointer would cause an overflow.
428-
if size <= len as u64 {
429-
throw_unsup_format!("OsString of length {} is too large for destination buffer of size {}", len, size)
420+
if size <= bytes.len() as u64 {
421+
throw_unsup_format!("OsString of length {} is too large for destination buffer of size {}", bytes.len(), size)
430422
}
431-
let actual_len = (len as u64)
432-
.checked_add(1)
433-
.map(Size::from_bytes)
434-
.ok_or_else(|| err_unsup_format!("OsString of length {} is too large", len))?;
435-
let this = self.eval_context_mut();
436-
this.memory.check_ptr_access(ptr.into(), actual_len, Align::from_bytes(1).unwrap())?;
437-
let buffer = this.memory.get_mut(ptr.alloc_id)?.get_bytes_mut(&*this.tcx, ptr, actual_len)?;
438-
buffer[..len].copy_from_slice(bytes);
439-
// This is ok because the buffer was strictly larger than `bytes`, so after adding the
440-
// null terminator, the buffer size is larger or equal to `bytes.len()`, meaning that
441-
// `bytes` actually fit inside tbe buffer.
442-
buffer[len] = 0;
443-
Ok(())
423+
// FIXME: We should use `Iterator::chain` instead when rust-lang/rust#65704 lands.
424+
self.eval_context_mut().memory.write_bytes(scalar, [bytes, &[0]].concat())
444425
}
445426
}
446427

src/shims/env.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
123123

124124
this.check_no_isolation("getcwd")?;
125125

126-
let buf = this.force_ptr(this.read_scalar(buf_op)?.not_undef()?)?;
126+
let buf = this.read_scalar(buf_op)?.not_undef()?;
127127
let size = this.read_scalar(size_op)?.to_usize(&*this.tcx)?;
128128
// If we cannot get the current directory, we return null
129129
match env::current_dir() {
130130
Ok(cwd) => {
131131
if this.write_os_str_to_c_string(&OsString::from(cwd), buf, size).is_ok() {
132-
return Ok(Scalar::Ptr(buf));
132+
return Ok(buf);
133133
}
134134
let erange = this.eval_libc("ERANGE")?;
135135
this.set_last_error(erange)?;

src/shims/foreign_items.rs

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5252
if zero_init {
5353
// We just allocated this, the access is definitely in-bounds.
5454
this.memory
55-
.get_mut(ptr.alloc_id)
56-
.unwrap()
57-
.write_repeat(&*this.tcx, ptr, 0, Size::from_bytes(size))
55+
.write_bytes(ptr.into(), itertools::repeat_n(0u8, size as usize))
5856
.unwrap();
5957
}
6058
Scalar::Ptr(ptr)
@@ -229,9 +227,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
229227
);
230228
// We just allocated this, the access is definitely in-bounds.
231229
this.memory
232-
.get_mut(ptr.alloc_id)
233-
.unwrap()
234-
.write_repeat(tcx, ptr, 0, Size::from_bytes(size))
230+
.write_bytes(ptr.into(), itertools::repeat_n(0u8, size as usize))
235231
.unwrap();
236232
this.write_scalar(Scalar::Ptr(ptr), dest)?;
237233
}
@@ -841,25 +837,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
841837
}
842838
"GetSystemInfo" => {
843839
let system_info = this.deref_operand(args[0])?;
844-
let system_info_ptr = this
845-
.check_mplace_access(system_info, None)?
846-
.expect("cannot be a ZST");
847-
// We rely on `deref_operand` doing bounds checks for us.
848840
// Initialize with `0`.
849841
this.memory
850-
.get_mut(system_info_ptr.alloc_id)?
851-
.write_repeat(tcx, system_info_ptr, 0, system_info.layout.size)?;
842+
.write_bytes(system_info.ptr, itertools::repeat_n(0, system_info.layout.size.bytes() as usize))?;
852843
// Set number of processors.
853844
let dword_size = Size::from_bytes(4);
854-
let offset = 2 * dword_size + 3 * tcx.pointer_size();
855-
this.memory
856-
.get_mut(system_info_ptr.alloc_id)?
857-
.write_scalar(
858-
tcx,
859-
system_info_ptr.offset(offset, tcx)?,
860-
Scalar::from_int(NUM_CPUS, dword_size).into(),
861-
dword_size,
862-
)?;
845+
let num_cpus = this.mplace_field(system_info, 6)?;
846+
this.write_scalar(
847+
Scalar::from_int(NUM_CPUS, dword_size),
848+
num_cpus.into(),
849+
)?;
863850
}
864851

865852
"TlsAlloc" => {

src/shims/intrinsics.rs

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
356356
_ => {
357357
// Do it in memory
358358
let mplace = this.force_allocation(dest)?;
359-
mplace.meta.unwrap_none();
360-
// not a zst, must be valid pointer
361-
let ptr = mplace.ptr.to_ptr()?;
362-
// we know the return place is in-bounds
363-
this.memory.get_mut(ptr.alloc_id)?.write_repeat(tcx, ptr, 0, dest.layout.size)?;
359+
mplace.meta.unwrap_none(); // must be sized
360+
this.memory.write_bytes(mplace.ptr, itertools::repeat_n(0, dest.layout.size.bytes() as usize))?;
364361
}
365362
}
366363
}
@@ -565,16 +562,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
565562
let ptr = this.read_scalar(args[0])?.not_undef()?;
566563
let count = this.read_scalar(args[2])?.to_usize(this)?;
567564
let byte_count = ty_layout.size * count;
568-
match this.memory.check_ptr_access(ptr, byte_count, ty_layout.align.abi)? {
569-
Some(ptr) => {
570-
this.memory
571-
.get_mut(ptr.alloc_id)?
572-
.write_repeat(tcx, ptr, val_byte, byte_count)?;
573-
}
574-
None => {
575-
// Size is 0, nothing to do.
576-
}
577-
}
565+
this.memory.write_bytes(ptr, itertools::repeat_n(val_byte, byte_count.bytes() as usize))?;
578566
}
579567

580568
name => throw_unsup_format!("unimplemented intrinsic: {}", name),

tests/run-pass/union-overwrite.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
#![feature(untagged_unions)]
2-
#![allow(unions_with_drop_fields)]
32

43
#[repr(C)]
4+
#[derive(Clone, Copy)]
55
struct Pair<T, U>(T, U);
66
#[repr(C)]
7+
#[derive(Clone, Copy)]
78
struct Triple<T>(T, T, T);
89

910
#[repr(C)]
10-
union U<A, B> {
11+
union U<A: Copy, B: Copy> {
1112
a: Pair<A, A>,
1213
b: B,
1314
}
1415

1516
#[repr(C)]
16-
union W<A, B> {
17+
union W<A: Copy, B: Copy> {
1718
a: A,
1819
b: B,
1920
}

0 commit comments

Comments
 (0)