Fix transmute on ByValPair

Fixes #227
This commit is contained in:
Ralf Jung 2017-07-03 13:57:18 -07:00
parent 8ff5d59efe
commit 030166757c
3 changed files with 24 additions and 9 deletions

View File

@ -1111,6 +1111,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
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");

View File

@ -395,16 +395,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
"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" => {

View File

@ -0,0 +1,17 @@
#![feature(core_intrinsics)]
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 9 def bytes followed by 7 undef bytes (the padding after the bool) in there.
let z : *const u8 = y as *const _ as *const _;
for i in 0..9 {
let byte = unsafe { *z.offset(i) };
assert_eq!(byte, 0);
}
let v = unsafe { *z.offset(9) };
if v == 0 {} //~ ERROR attempted to read undefined bytes
}