Rollup merge of #90892 - RalfJung:miri-partial-ptr-copy, r=oli-obk

fix ICE on Miri/CTFE copy of half a pointer

Fixes https://github.com/rust-lang/miri/issues/1910
r? `````@oli-obk`````
This commit is contained in:
Yuki Okushi 2021-11-16 09:14:22 +09:00 committed by GitHub
commit fff9055afb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 10 deletions

View file

@ -1057,20 +1057,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
Some(dest_ptr) => dest_ptr,
};
// first copy the relocations to a temporary buffer, because
// `get_bytes_mut` will clear the relocations, which is correct,
// since we don't want to keep any relocations at the target.
// (`get_bytes_with_uninit_and_ptr` below checks that there are no
// relocations overlapping the edges; those would not be handled correctly).
let relocations =
src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies);
// Prepare a copy of the initialization mask.
let compressed = src_alloc.compress_uninit_range(src_range);
// This checks relocation edges on the src.
// This checks relocation edges on the src, which needs to happen before
// `prepare_relocation_copy`.
let src_bytes = src_alloc
.get_bytes_with_uninit_and_ptr(&tcx, src_range)
.map_err(|e| e.to_interp_error(src_alloc_id))?
.as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
// first copy the relocations to a temporary buffer, because
// `get_bytes_mut` will clear the relocations, which is correct,
// since we don't want to keep any relocations at the target.
let relocations =
src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies);
// Prepare a copy of the initialization mask.
let compressed = src_alloc.compress_uninit_range(src_range);
// Destination alloc preparations and access hooks.
let (dest_alloc, extra) = self.get_raw_mut(dest_alloc_id)?;

View file

@ -0,0 +1,12 @@
// error-pattern unable to turn pointer into raw bytes
#![feature(const_ptr_read)]
#![feature(const_ptr_offset)]
const C: () = unsafe {
let foo = Some(&42 as *const i32);
let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3;
(&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
};
fn main() {
}

View file

@ -0,0 +1,26 @@
error: any use of this value will cause an error
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
|
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| unable to turn pointer into raw bytes
| inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
| inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
| inside `C` at $DIR/issue-miri-1910.rs:8:5
|
::: $DIR/issue-miri-1910.rs:5:1
|
LL | / const C: () = unsafe {
LL | | let foo = Some(&42 as *const i32);
LL | | let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3;
LL | | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
LL | | };
| |__-
|
= note: `#[deny(const_err)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
error: aborting due to previous error