Skip to content

Commit 94ca0b3

Browse files
committed
fix ICE on Miri/CTFE copy of half a pointer
1 parent 1b12d01 commit 94ca0b3

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

compiler/rustc_const_eval/src/interpret/memory.rs

+6-7
Original file line numberDiff line numberDiff line change
@@ -1057,20 +1057,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
10571057
Some(dest_ptr) => dest_ptr,
10581058
};
10591059

1060+
// This checks relocation edges on the src, which needs to happen before
1061+
// `prepare_relocation_copy`.
1062+
let src_bytes = src_alloc
1063+
.get_bytes_with_uninit_and_ptr(&tcx, src_range)
1064+
.map_err(|e| e.to_interp_error(src_alloc_id))?
1065+
.as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
10601066
// first copy the relocations to a temporary buffer, because
10611067
// `get_bytes_mut` will clear the relocations, which is correct,
10621068
// since we don't want to keep any relocations at the target.
1063-
// (`get_bytes_with_uninit_and_ptr` below checks that there are no
1064-
// relocations overlapping the edges; those would not be handled correctly).
10651069
let relocations =
10661070
src_alloc.prepare_relocation_copy(self, src_range, dest_offset, num_copies);
10671071
// Prepare a copy of the initialization mask.
10681072
let compressed = src_alloc.compress_uninit_range(src_range);
1069-
// This checks relocation edges on the src.
1070-
let src_bytes = src_alloc
1071-
.get_bytes_with_uninit_and_ptr(&tcx, src_range)
1072-
.map_err(|e| e.to_interp_error(src_alloc_id))?
1073-
.as_ptr(); // raw ptr, so we can also get a ptr to the destination allocation
10741073

10751074
// Destination alloc preparations and access hooks.
10761075
let (dest_alloc, extra) = self.get_raw_mut(dest_alloc_id)?;

src/test/ui/consts/issue-miri-1910.rs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// error-pattern unable to turn pointer into raw bytes
2+
#![feature(const_ptr_read)]
3+
#![feature(const_ptr_offset)]
4+
5+
const C: () = unsafe {
6+
let foo = Some(&42 as *const i32);
7+
let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3;
8+
(&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
9+
};
10+
11+
fn main() {
12+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: any use of this value will cause an error
2+
--> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
3+
|
4+
LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1);
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
| |
7+
| unable to turn pointer into raw bytes
8+
| inside `std::ptr::read::<u8>` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL
9+
| inside `ptr::const_ptr::<impl *const u8>::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
10+
| inside `C` at $DIR/issue-miri-1910.rs:8:5
11+
|
12+
::: $DIR/issue-miri-1910.rs:5:1
13+
|
14+
LL | / const C: () = unsafe {
15+
LL | | let foo = Some(&42 as *const i32);
16+
LL | | let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3;
17+
LL | | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read();
18+
LL | | };
19+
| |__-
20+
|
21+
= note: `#[deny(const_err)]` on by default
22+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
23+
= note: for more information, see issue #71800 <https://github.com/rust-lang/rust/issues/71800>
24+
25+
error: aborting due to previous error
26+

0 commit comments

Comments
 (0)