Retag argument to drop_in_place
unconditionally
This commit is contained in:
parent
102040ce76
commit
c359ab0b5d
6 changed files with 34 additions and 47 deletions
|
@ -174,35 +174,36 @@ fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>)
|
||||||
let mut body =
|
let mut body =
|
||||||
new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
|
new_body(source, blocks, local_decls_for_sig(&sig, span), sig.inputs().len(), span);
|
||||||
|
|
||||||
if ty.is_some() {
|
// The first argument (index 0), but add 1 for the return value.
|
||||||
// The first argument (index 0), but add 1 for the return value.
|
let mut dropee_ptr = Place::from(Local::new(1 + 0));
|
||||||
let mut dropee_ptr = Place::from(Local::new(1 + 0));
|
if tcx.sess.opts.unstable_opts.mir_emit_retag {
|
||||||
if tcx.sess.opts.unstable_opts.mir_emit_retag {
|
// We want to treat the function argument as if it was passed by `&mut`. As such, we
|
||||||
// We want to treat the function argument as if it was passed by `&mut`. As such, we
|
// generate
|
||||||
// generate
|
// ```
|
||||||
// ```
|
// temp = &mut *arg;
|
||||||
// temp = &mut *arg;
|
// Retag(temp, FnEntry)
|
||||||
// Retag(temp, FnEntry)
|
// ```
|
||||||
// ```
|
// It's important that we do this first, before anything that depends on `dropee_ptr`
|
||||||
// It's important that we do this first, before anything that depends on `dropee_ptr`
|
// has been put into the body.
|
||||||
// has been put into the body.
|
let reborrow = Rvalue::Ref(
|
||||||
let reborrow = Rvalue::Ref(
|
tcx.lifetimes.re_erased,
|
||||||
tcx.lifetimes.re_erased,
|
BorrowKind::Mut { allow_two_phase_borrow: false },
|
||||||
BorrowKind::Mut { allow_two_phase_borrow: false },
|
tcx.mk_place_deref(dropee_ptr),
|
||||||
tcx.mk_place_deref(dropee_ptr),
|
);
|
||||||
);
|
let ref_ty = reborrow.ty(body.local_decls(), tcx);
|
||||||
let ref_ty = reborrow.ty(body.local_decls(), tcx);
|
dropee_ptr = body.local_decls.push(LocalDecl::new(ref_ty, span)).into();
|
||||||
dropee_ptr = body.local_decls.push(LocalDecl::new(ref_ty, span)).into();
|
let new_statements = [
|
||||||
let new_statements = [
|
StatementKind::Assign(Box::new((dropee_ptr, reborrow))),
|
||||||
StatementKind::Assign(Box::new((dropee_ptr, reborrow))),
|
StatementKind::Retag(RetagKind::FnEntry, Box::new(dropee_ptr)),
|
||||||
StatementKind::Retag(RetagKind::FnEntry, Box::new(dropee_ptr)),
|
];
|
||||||
];
|
for s in new_statements {
|
||||||
for s in new_statements {
|
body.basic_blocks_mut()[START_BLOCK]
|
||||||
body.basic_blocks_mut()[START_BLOCK]
|
.statements
|
||||||
.statements
|
.push(Statement { source_info, kind: s });
|
||||||
.push(Statement { source_info, kind: s });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ty.is_some() {
|
||||||
let patch = {
|
let patch = {
|
||||||
let param_env = tcx.param_env_reveal_all_normalized(def_id);
|
let param_env = tcx.param_env_reveal_all_normalized(def_id);
|
||||||
let mut elaborator =
|
let mut elaborator =
|
||||||
|
|
|
@ -10,7 +10,7 @@ impl Drop for HasDrop {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _val = *P;
|
let _val = *P;
|
||||||
//~^ ERROR: /not granting access .* because that would remove .* which is protected/
|
//~^ ERROR: /not granting access .* because that would remove .* which is strongly protected/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is protected because it is an argument of call ID
|
error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||||
--> $DIR/drop_in_place_protector.rs:LL:CC
|
--> $DIR/drop_in_place_protector.rs:LL:CC
|
||||||
|
|
|
|
||||||
LL | let _val = *P;
|
LL | let _val = *P;
|
||||||
| ^^ not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is protected because it is an argument of call ID
|
| ^^ not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID
|
||||||
|
|
|
|
||||||
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
|
||||||
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
|
||||||
|
|
|
@ -3,16 +3,9 @@
|
||||||
|
|
||||||
//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/
|
//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/
|
||||||
|
|
||||||
#[repr(transparent)]
|
|
||||||
struct HasDrop;
|
|
||||||
|
|
||||||
impl Drop for HasDrop {
|
|
||||||
fn drop(&mut self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let x = (0u8, HasDrop);
|
let x = 0u8;
|
||||||
let x = core::ptr::addr_of!(x);
|
let x = core::ptr::addr_of!(x);
|
||||||
core::ptr::drop_in_place(x.cast_mut());
|
core::ptr::drop_in_place(x.cast_mut());
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ help: <TAG> was created by a SharedReadOnly retag at offsets [0x0..0x1]
|
||||||
LL | let x = core::ptr::addr_of!(x);
|
LL | let x = core::ptr::addr_of!(x);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: BACKTRACE:
|
= note: BACKTRACE:
|
||||||
= note: inside `std::ptr::drop_in_place::<(u8, HasDrop)> - shim(Some((u8, HasDrop)))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
|
= note: inside `std::ptr::drop_in_place::<u8> - shim(None)` at RUSTLIB/core/src/ptr/mod.rs:LL:CC
|
||||||
note: inside `main` at $DIR/drop_in_place_retag.rs:LL:CC
|
note: inside `main` at $DIR/drop_in_place_retag.rs:LL:CC
|
||||||
--> $DIR/drop_in_place_retag.rs:LL:CC
|
--> $DIR/drop_in_place_retag.rs:LL:CC
|
||||||
|
|
|
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
// Make sure that dropping types with no drop glue is DB even for invalid pointers.
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
unsafe {
|
|
||||||
core::ptr::drop_in_place::<u8>(core::ptr::null_mut());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue