Merge pull request #233 from RalfJung/transmute

Fix transmute on ByValPair
This commit is contained in:
Oliver Schneider
2017-07-04 08:32:46 +02:00
committed by GitHub
3 changed files with 27 additions and 9 deletions
+4
View File
@@ -1111,6 +1111,10 @@ pub(super) fn write_value(
dest: Lvalue<'tcx>,
dest_ty: Ty<'tcx>,
) -> EvalResult<'tcx> {
// Note that it is really important that the type here is the right one, and matches the type things are read at.
// In case `src_val` is a `ByValPair`, we don't do any magic here to handle padding properly, which is only
// correct if we never look at this data with the wrong type.
match dest {
Lvalue::Global(cid) => {
let dest = *self.globals.get_mut(&cid).expect("global should be cached");
+3 -9
View File
@@ -395,16 +395,10 @@ pub(super) fn call_intrinsic(
"transmute" => {
let src_ty = substs.type_at(0);
let dest_ty = substs.type_at(1);
let src_align = self.type_align(src_ty)?;
let dest_align = self.type_align(dest_ty)?;
let size = self.type_size(dest_ty)?.expect("transmute() type must be sized");
if dest_align < src_align {
let ptr = self.force_allocation(dest)?.to_ptr()?;
self.memory.mark_packed(ptr, size);
self.write_value_to_ptr(arg_vals[0], PrimVal::Ptr(ptr), dest_ty)?;
} else {
self.write_value(arg_vals[0], dest, dest_ty)?;
}
let ptr = self.force_allocation(dest)?.to_ptr()?;
self.memory.mark_packed(ptr, size);
self.write_value_to_ptr(arg_vals[0], PrimVal::Ptr(ptr), src_ty)?;
}
"uninit" => {
@@ -0,0 +1,20 @@
#![feature(core_intrinsics)]
use std::mem;
fn main() {
let x: Option<Box<[u8]>> = unsafe {
let z = std::intrinsics::add_with_overflow(0usize, 0usize);
std::mem::transmute::<(usize, bool), Option<Box<[u8]>>>(z)
};
let y = &x;
// Now read this bytewise. There should be (ptr_size+1) def bytes followed by (ptr_size-1) undef bytes (the padding after the bool) in there.
let z : *const u8 = y as *const _ as *const _;
let first_undef = mem::size_of::<usize>() as isize + 1;
for i in 0..first_undef {
let byte = unsafe { *z.offset(i) };
assert_eq!(byte, 0);
}
let v = unsafe { *z.offset(first_undef) };
if v == 0 {} //~ ERROR attempted to read undefined bytes
}