Skip to content

Commit

Permalink
fix ICE on Miri/CTFE copy of half a pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Nov 14, 2021
1 parent 1b12d01 commit 94ca0b3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 7 deletions.
13 changes: 6 additions & 7 deletions compiler/rustc_const_eval/src/interpret/memory.rs
Expand Up @@ -1057,20 +1057,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
Some(dest_ptr) => dest_ptr,
};

// 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.
// (`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.
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

// Destination alloc preparations and access hooks.
let (dest_alloc, extra) = self.get_raw_mut(dest_alloc_id)?;
Expand Down
12 changes: 12 additions & 0 deletions src/test/ui/consts/issue-miri-1910.rs
@@ -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() {
}
26 changes: 26 additions & 0 deletions src/test/ui/consts/issue-miri-1910.stderr
@@ -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

0 comments on commit 94ca0b3

Please sign in to comment.