fix alignment handling for Repeat expressions
This commit is contained in:
parent
4c9ac1e93b
commit
b169ee7c1a
@ -208,13 +208,13 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
let rest_ptr = first_ptr.offset(elem_size, self)?;
|
let rest_ptr = first_ptr.offset(elem_size, self)?;
|
||||||
// For the alignment of `rest_ptr`, we crucially do *not* use `first.align` as
|
// For the alignment of `rest_ptr`, we crucially do *not* use `first.align` as
|
||||||
// that place might be more aligned than its type mandates (a `u8` array could
|
// that place might be more aligned than its type mandates (a `u8` array could
|
||||||
// be 4-aligned if it sits at the right spot in a struct). Instead we use
|
// be 4-aligned if it sits at the right spot in a struct). We have to also factor
|
||||||
// `first.layout.align`, i.e., the alignment given by the type.
|
// in element size.
|
||||||
self.mem_copy_repeatedly(
|
self.mem_copy_repeatedly(
|
||||||
first_ptr,
|
first_ptr,
|
||||||
first.align,
|
dest.align,
|
||||||
rest_ptr,
|
rest_ptr,
|
||||||
first.layout.align.abi,
|
dest.align.restrict_for_offset(elem_size),
|
||||||
elem_size,
|
elem_size,
|
||||||
length - 1,
|
length - 1,
|
||||||
/*nonoverlapping:*/ true,
|
/*nonoverlapping:*/ true,
|
||||||
|
22
src/tools/miri/tests/pass/align_repeat_into_packed_field.rs
Normal file
22
src/tools/miri/tests/pass/align_repeat_into_packed_field.rs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#![feature(custom_mir, core_intrinsics)]
|
||||||
|
use std::intrinsics::mir::*;
|
||||||
|
|
||||||
|
#[repr(packed)]
|
||||||
|
struct S { field: [u32; 2] }
|
||||||
|
|
||||||
|
#[custom_mir(dialect = "runtime", phase = "optimized")]
|
||||||
|
fn test() { mir! {
|
||||||
|
let s: S;
|
||||||
|
{
|
||||||
|
// Store a repeat expression directly into a field of a packed struct.
|
||||||
|
s.field = [0; 2];
|
||||||
|
Return()
|
||||||
|
}
|
||||||
|
} }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// Run this a bunch of time to make sure it doesn't pass by chance.
|
||||||
|
for _ in 0..20 {
|
||||||
|
test();
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,8 @@ use std::mem::size_of;
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut a = Params::new();
|
let mut a = Params::new();
|
||||||
|
// The array itself here happens to be quite well-aligned, but not all its elements have that
|
||||||
|
// large alignment and we better make sure that is still accepted by Miri.
|
||||||
a.key_block = [0; BLOCKBYTES];
|
a.key_block = [0; BLOCKBYTES];
|
||||||
}
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user