parent
8ff5d59efe
commit
030166757c
@ -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");
|
||||
|
@ -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" => {
|
||||
|
17
tests/compile-fail/transmute-pair-undef.rs
Normal file
17
tests/compile-fail/transmute-pair-undef.rs
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user