Skip to content

Commit 51cffba

Browse files
committed
Auto merge of #830 - RalfJung:check-place, r=RalfJung
Fix validation and reborrowing of integer pointers Depends on rust-lang/rust#62441
2 parents 0b9434c + 11686f4 commit 51cffba

10 files changed

+33
-38
lines changed

rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0b680cfce544ff9a59d720020e397c4bf3346650
1+
d4e15655092d1bdae79619eb0ff2c3cb5468fc36

src/eval.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,6 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
108108
ecx.machine.argc = Some(argc_place.ptr.to_ptr()?);
109109
}
110110

111-
// FIXME: extract main source file path.
112111
// Third argument (`argv`): created from `config.args`.
113112
let dest = ecx.eval_place(&mir::Place::Base(mir::PlaceBase::Local(args.next().unwrap())))?;
114113
// For Windows, construct a command string with all the aguments.
@@ -136,7 +135,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
136135
let place = ecx.mplace_field(argvs_place, idx as u64)?;
137136
ecx.write_scalar(Scalar::Ptr(arg), place.into())?;
138137
}
139-
ecx.memory_mut().mark_immutable(argvs_place.to_ptr()?.alloc_id)?;
138+
ecx.memory_mut().mark_immutable(argvs_place.ptr.assert_ptr().alloc_id)?;
140139
// Write a pointer to that place as the argument.
141140
let argv = argvs_place.ptr;
142141
ecx.write_scalar(argv, dest)?;

src/helpers.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -116,36 +116,32 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
116116
.map(|(size, _)| size)
117117
.unwrap_or_else(|| place.layout.size)
118118
);
119-
assert!(size.bytes() > 0);
120119
// Store how far we proceeded into the place so far. Everything to the left of
121120
// this offset has already been handled, in the sense that the frozen parts
122121
// have had `action` called on them.
123-
let mut end_ptr = place.ptr;
122+
let mut end_ptr = place.ptr.assert_ptr();
124123
// Called when we detected an `UnsafeCell` at the given offset and size.
125124
// Calls `action` and advances `end_ptr`.
126125
let mut unsafe_cell_action = |unsafe_cell_ptr: Scalar<Tag>, unsafe_cell_size: Size| {
127-
if unsafe_cell_size != Size::ZERO {
128-
debug_assert_eq!(unsafe_cell_ptr.to_ptr().unwrap().alloc_id,
129-
end_ptr.to_ptr().unwrap().alloc_id);
130-
debug_assert_eq!(unsafe_cell_ptr.to_ptr().unwrap().tag,
131-
end_ptr.to_ptr().unwrap().tag);
132-
}
126+
let unsafe_cell_ptr = unsafe_cell_ptr.assert_ptr();
127+
debug_assert_eq!(unsafe_cell_ptr.alloc_id, end_ptr.alloc_id);
128+
debug_assert_eq!(unsafe_cell_ptr.tag, end_ptr.tag);
133129
// We assume that we are given the fields in increasing offset order,
134130
// and nothing else changes.
135-
let unsafe_cell_offset = unsafe_cell_ptr.get_ptr_offset(this);
136-
let end_offset = end_ptr.get_ptr_offset(this);
131+
let unsafe_cell_offset = unsafe_cell_ptr.offset;
132+
let end_offset = end_ptr.offset;
137133
assert!(unsafe_cell_offset >= end_offset);
138134
let frozen_size = unsafe_cell_offset - end_offset;
139135
// Everything between the end_ptr and this `UnsafeCell` is frozen.
140136
if frozen_size != Size::ZERO {
141-
action(end_ptr.to_ptr()?, frozen_size, /*frozen*/true)?;
137+
action(end_ptr, frozen_size, /*frozen*/true)?;
142138
}
143139
// This `UnsafeCell` is NOT frozen.
144140
if unsafe_cell_size != Size::ZERO {
145-
action(unsafe_cell_ptr.to_ptr()?, unsafe_cell_size, /*frozen*/false)?;
141+
action(unsafe_cell_ptr, unsafe_cell_size, /*frozen*/false)?;
146142
}
147143
// Update end end_ptr.
148-
end_ptr = unsafe_cell_ptr.ptr_wrapping_offset(unsafe_cell_size, this);
144+
end_ptr = unsafe_cell_ptr.wrapping_offset(unsafe_cell_size, this);
149145
// Done
150146
Ok(())
151147
};
@@ -234,7 +230,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
234230
layout::FieldPlacement::Arbitrary { .. } => {
235231
// Gather the subplaces and sort them before visiting.
236232
let mut places = fields.collect::<InterpResult<'tcx, Vec<MPlaceTy<'tcx, Tag>>>>()?;
237-
places.sort_by_key(|place| place.ptr.get_ptr_offset(self.ecx()));
233+
places.sort_by_key(|place| place.ptr.assert_ptr().offset);
238234
self.walk_aggregate(place, places.into_iter().map(Ok))
239235
}
240236
layout::FieldPlacement::Union { .. } => {

src/shims/foreign_items.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -842,13 +842,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
842842
},
843843
"GetSystemInfo" => {
844844
let system_info = this.deref_operand(args[0])?;
845-
let (system_info_ptr, align) = system_info.to_scalar_ptr_align();
846-
let system_info_ptr = this.memory()
847-
.check_ptr_access(
848-
system_info_ptr,
849-
system_info.layout.size,
850-
align,
851-
)?
845+
let system_info_ptr = this.check_mplace_access(system_info, None)?
852846
.expect("cannot be a ZST");
853847
// Initialize with `0`.
854848
this.memory_mut().get_mut(system_info_ptr.alloc_id)?

src/shims/intrinsics.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
166166
let elem_size = elem_layout.size.bytes();
167167
let count = this.read_scalar(args[2])?.to_usize(this)?;
168168
let elem_align = elem_layout.align.abi;
169-
// erase tags: this is a raw ptr operation
169+
170+
let size = Size::from_bytes(count * elem_size);
170171
let src = this.read_scalar(args[0])?.not_undef()?;
172+
let src = this.memory().check_ptr_access(src, size, elem_align)?;
171173
let dest = this.read_scalar(args[1])?.not_undef()?;
172-
this.memory_mut().copy(
173-
src,
174-
elem_align,
175-
dest,
176-
elem_align,
177-
Size::from_bytes(count * elem_size),
178-
intrinsic_name.ends_with("_nonoverlapping"),
179-
)?;
174+
let dest = this.memory().check_ptr_access(dest, size, elem_align)?;
175+
176+
if let (Some(src), Some(dest)) = (src, dest) {
177+
this.memory_mut().copy(
178+
src,
179+
dest,
180+
size,
181+
intrinsic_name.ends_with("_nonoverlapping"),
182+
)?;
183+
}
180184
}
181185

182186
"discriminant_value" => {

src/stacked_borrows.rs

+1
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
587587
// Nothing to do for ZSTs.
588588
return Ok(*val);
589589
}
590+
let place = this.force_mplace_ptr(place)?;
590591

591592
// Compute new borrow.
592593
let new_tag = match kind {

test-cargo-miri/run-test.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ def test_cargo_miri_run():
5252
)
5353

5454
def test_cargo_miri_test():
55-
# FIXME: enable validation again, once that no longer conflicts with intptrcast
5655
test("cargo miri test",
57-
cargo_miri("test") + ["--", "-Zmiri-seed=feed", "-Zmiri-disable-validation"],
56+
cargo_miri("test") + ["--", "-Zmiri-seed=feed"],
5857
"test.stdout.ref", "test.stderr.ref"
5958
)
6059
test("cargo miri test (with filter)",

tests/run-pass/unique-send.rs tests/run-pass/mpsc.rs

+5
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,9 @@ pub fn main() {
77
tx.send(box 100).unwrap();
88
let v = rx.recv().unwrap();
99
assert_eq!(v, box 100);
10+
11+
tx.send(box 101).unwrap();
12+
tx.send(box 102).unwrap();
13+
assert_eq!(rx.recv().unwrap(), box 101);
14+
assert_eq!(rx.recv().unwrap(), box 102);
1015
}

tests/run-pass-noseed/ptr_int_casts.rs tests/run-pass/ptr_int_casts.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// FIXME move this to run-pass, it should work with intptrcast.
21
use std::mem;
32
use std::ptr;
43

tests/run-pass-noseed/ptr_offset.rs tests/run-pass/ptr_offset.rs

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// FIXME move this to run-pass, it should work with intptrcast.
2-
31
fn f() -> i32 { 42 }
42

53
fn main() {

0 commit comments

Comments
 (0)