Skip to content

Commit fa33d6e

Browse files
authored
Rollup merge of #114296 - RalfJung:interpret-repeat-align, r=oli-obk
interpret: fix alignment handling for Repeat expressions
2 parents c726dcb + b169ee7 commit fa33d6e

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

compiler/rustc_const_eval/src/interpret/step.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
208208
let rest_ptr = first_ptr.offset(elem_size, self)?;
209209
// For the alignment of `rest_ptr`, we crucially do *not* use `first.align` as
210210
// that place might be more aligned than its type mandates (a `u8` array could
211-
// be 4-aligned if it sits at the right spot in a struct). Instead we use
212-
// `first.layout.align`, i.e., the alignment given by the type.
211+
// be 4-aligned if it sits at the right spot in a struct). We have to also factor
212+
// in element size.
213213
self.mem_copy_repeatedly(
214214
first_ptr,
215-
first.align,
215+
dest.align,
216216
rest_ptr,
217-
first.layout.align.abi,
217+
dest.align.restrict_for_offset(elem_size),
218218
elem_size,
219219
length - 1,
220220
/*nonoverlapping:*/ true,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![feature(custom_mir, core_intrinsics)]
2+
use std::intrinsics::mir::*;
3+
4+
#[repr(packed)]
5+
struct S { field: [u32; 2] }
6+
7+
#[custom_mir(dialect = "runtime", phase = "optimized")]
8+
fn test() { mir! {
9+
let s: S;
10+
{
11+
// Store a repeat expression directly into a field of a packed struct.
12+
s.field = [0; 2];
13+
Return()
14+
}
15+
} }
16+
17+
fn main() {
18+
// Run this a bunch of time to make sure it doesn't pass by chance.
19+
for _ in 0..20 {
20+
test();
21+
}
22+
}

src/tools/miri/tests/pass/issues/issue-miri-1925.rs renamed to src/tools/miri/tests/pass/align_repeat_into_well_aligned_array.rs

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::mem::size_of;
44

55
fn main() {
66
let mut a = Params::new();
7+
// The array itself here happens to be quite well-aligned, but not all its elements have that
8+
// large alignment and we better make sure that is still accepted by Miri.
79
a.key_block = [0; BLOCKBYTES];
810
}
911

0 commit comments

Comments
 (0)