diff --git a/src/terminator/intrinsic.rs b/src/terminator/intrinsic.rs index ab8539be31..51404e7d13 100644 --- a/src/terminator/intrinsic.rs +++ b/src/terminator/intrinsic.rs @@ -402,6 +402,18 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { } } + "write_bytes" => { + let u8 = self.tcx.types.u8; + let ty = substs.type_at(0); + let ty_align = self.type_align(ty)?; + let val_byte = self.value_to_primval(arg_vals[1], u8)?.to_u128()? as u8; + let size = self.type_size(ty)?.expect("write_bytes() type must be sized"); + let ptr = arg_vals[0].read_ptr(&self.memory)?; + let count = self.value_to_primval(arg_vals[2], usize)?.to_u64()?; + self.memory.check_align(ptr, size * count, ty_align)?; + self.memory.write_repeat(ptr, val_byte, size * count)?; + } + name => return Err(EvalError::Unimplemented(format!("unimplemented intrinsic: {}", name))), } diff --git a/tests/run-pass/write-bytes.rs b/tests/run-pass/write-bytes.rs new file mode 100644 index 0000000000..7c9a38fca6 --- /dev/null +++ b/tests/run-pass/write-bytes.rs @@ -0,0 +1,45 @@ +#[repr(C)] +#[derive(Copy, Clone)] +struct Foo { + a: u64, + b: u64, + c: u64, +} + +fn main() { + const LENGTH: usize = 10; + let mut v: [u64; LENGTH] = [0; LENGTH]; + + for idx in 0..LENGTH { + assert_eq!(v[idx], 0); + } + + unsafe { + let p = v.as_mut_ptr(); + ::std::ptr::write_bytes(p, 0xab, LENGTH); + } + + for idx in 0..LENGTH { + assert_eq!(v[idx], 0xabababababababab); + } + + // ----- + + let mut w: [Foo; LENGTH] = [Foo { a: 0, b: 0, c: 0 }; LENGTH]; + for idx in 0..LENGTH { + assert_eq!(w[idx].a, 0); + assert_eq!(w[idx].b, 0); + assert_eq!(w[idx].c, 0); + } + + unsafe { + let p = w.as_mut_ptr(); + ::std::ptr::write_bytes(p, 0xcd, LENGTH); + } + + for idx in 0..LENGTH { + assert_eq!(w[idx].a, 0xcdcdcdcdcdcdcdcd); + assert_eq!(w[idx].b, 0xcdcdcdcdcdcdcdcd); + assert_eq!(w[idx].c, 0xcdcdcdcdcdcdcdcd); + } +}