mirror of
https://github.com/rust-lang/rust.git
synced 2026-06-03 01:16:14 +03:00
Merge pull request #233 from RalfJung/transmute
Fix transmute on ByValPair
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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
|
||||
}
|
||||
Reference in New Issue
Block a user