diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index e9cf11424cae..ba1028f76c1c 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -189,12 +189,22 @@ pub use intrinsics::write_bytes; /// i.e., you do not usually have to worry about such issues unless you call `drop_in_place` /// manually. #[stable(feature = "drop_in_place", since = "1.8.0")] +#[inline(always)] +pub unsafe fn drop_in_place(to_drop: *mut T) { + real_drop_in_place(&mut *to_drop) +} + +// The real `drop_in_place` -- the one that gets called implicitly when variables go +// out of scope -- should have a safe reference and not a raw pointer as argument +// type. When we drop a local variable, we access it with a pointer that behaves +// like a safe reference; transmuting that to a raw pointer does not mean we can +// actually access it with raw pointers. #[lang = "drop_in_place"] #[allow(unconditional_recursion)] -pub unsafe fn drop_in_place(to_drop: *mut T) { +unsafe fn real_drop_in_place(to_drop: &mut T) { // Code here does not matter - this is replaced by the // real drop glue by the compiler. - drop_in_place(to_drop); + real_drop_in_place(to_drop) } /// Creates a null raw pointer. diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 6070b31d3e7a..448946567974 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -196,6 +196,9 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // that will take care to make it UB to leave the range, just // like for transmute). caller.value == callee.value, + (layout::Abi::ScalarPair(ref caller1, ref caller2), + layout::Abi::ScalarPair(ref callee1, ref callee2)) => + caller1.value == callee1.value && caller2.value == callee2.value, // Be conservative _ => false } diff --git a/src/librustc_mir/shim.rs b/src/librustc_mir/shim.rs index 93bf1b3e36e3..04079319a787 100644 --- a/src/librustc_mir/shim.rs +++ b/src/librustc_mir/shim.rs @@ -226,8 +226,13 @@ fn build_drop_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // The first argument (index 0), but add 1 for the return value. let dropee_ptr = Place::Local(Local::new(1+0)); if tcx.sess.opts.debugging_opts.mir_emit_retag { - // We use raw ptr operations, better prepare the alias tracking for that + // Function arguments should be retagged mir.basic_blocks_mut()[START_BLOCK].statements.insert(0, Statement { + source_info, + kind: StatementKind::Retag { fn_entry: true, place: dropee_ptr.clone() }, + }); + // We use raw ptr operations, better prepare the alias tracking for that + mir.basic_blocks_mut()[START_BLOCK].statements.insert(1, Statement { source_info, kind: StatementKind::EscapeToRaw(Operand::Copy(dropee_ptr.clone())), })