Skip to content

Commit 959f764

Browse files
authored
Rollup merge of rust-lang#36459 - nikomatsakis:issue-35546, r=eddyb
invoke drop glue with a ptr to (data, meta) This is done by creating a little space on the stack. Hokey, but it's the simplest fix I can see, and I am in "kill regressions" mode right now. Fixes rust-lang#35546 r? @eddyb
2 parents 69a7f92 + 693676d commit 959f764

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

src/librustc_trans/glue.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ fn trans_custom_dtor<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
296296
sized_args = [v0];
297297
&sized_args
298298
} else {
299+
// FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
299300
unsized_args = [
300301
Load(bcx, get_dataptr(bcx, v0)),
301302
Load(bcx, get_meta(bcx, v0))
@@ -440,7 +441,9 @@ pub fn size_and_align_of_dst<'blk, 'tcx>(bcx: &BlockAndBuilder<'blk, 'tcx>,
440441
}
441442
}
442443

443-
fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueKind<'tcx>)
444+
fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
445+
v0: ValueRef,
446+
g: DropGlueKind<'tcx>)
444447
-> Block<'blk, 'tcx> {
445448
let t = g.ty();
446449

@@ -463,6 +466,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
463466
let llval = get_dataptr(bcx, v0);
464467
let llbox = Load(bcx, llval);
465468
let bcx = drop_ty(bcx, v0, content_ty, DebugLoc::None);
469+
// FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
466470
let info = get_meta(bcx, v0);
467471
let info = Load(bcx, info);
468472
let (llsize, llalign) =
@@ -488,6 +492,7 @@ fn make_drop_glue<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, v0: ValueRef, g: DropGlueK
488492
// No support in vtable for distinguishing destroying with
489493
// versus without calling Drop::drop. Assert caller is
490494
// okay with always calling the Drop impl, if any.
495+
// FIXME(#36457) -- we should pass unsized values to drop glue as two arguments
491496
assert!(!skip_dtor);
492497
let data_ptr = get_dataptr(bcx, v0);
493498
let vtable_ptr = Load(bcx, get_meta(bcx, v0));
@@ -543,6 +548,7 @@ fn drop_structural_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
543548
let value = if type_is_sized(cx.tcx(), t) {
544549
adt::MaybeSizedValue::sized(av)
545550
} else {
551+
// FIXME(#36457) -- we should pass unsized values as two arguments
546552
let data = Load(cx, get_dataptr(cx, av));
547553
let info = Load(cx, get_meta(cx, av));
548554
adt::MaybeSizedValue::unsized_(data, info)
@@ -586,6 +592,7 @@ fn drop_structural_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
586592
let val = if type_is_sized(cx.tcx(), field_ty) {
587593
llfld_a
588594
} else {
595+
// FIXME(#36457) -- we should pass unsized values as two arguments
589596
let scratch = alloc_ty(cx, field_ty, "__fat_ptr_iter");
590597
Store(cx, llfld_a, get_dataptr(cx, scratch));
591598
Store(cx, value.meta, get_meta(cx, scratch));

src/librustc_trans/intrinsic.rs

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
194194
let ptr = if is_sized {
195195
llargs[0]
196196
} else {
197+
// FIXME(#36457) -- we should pass unsized values as two arguments
197198
let scratch = alloc_ty(bcx, tp_ty, "drop");
198199
call_lifetime_start(bcx, scratch);
199200
Store(bcx, llargs[0], get_dataptr(bcx, scratch));

src/librustc_trans/mir/block.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -242,10 +242,28 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
242242
let lvalue = self.trans_lvalue(&bcx, location);
243243
let drop_fn = glue::get_drop_glue(bcx.ccx(), ty);
244244
let drop_ty = glue::get_drop_glue_type(bcx.tcx(), ty);
245-
let llvalue = if drop_ty != ty {
246-
bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
245+
let is_sized = common::type_is_sized(bcx.tcx(), ty);
246+
let llvalue = if is_sized {
247+
if drop_ty != ty {
248+
bcx.pointercast(lvalue.llval, type_of::type_of(bcx.ccx(), drop_ty).ptr_to())
249+
} else {
250+
lvalue.llval
251+
}
247252
} else {
248-
lvalue.llval
253+
// FIXME(#36457) Currently drop glue takes sized
254+
// values as a `*(data, meta)`, but elsewhere in
255+
// MIR we pass `(data, meta)` as two separate
256+
// arguments. It would be better to fix drop glue,
257+
// but I am shooting for a quick fix to #35546
258+
// here that can be cleanly backported to beta, so
259+
// I want to avoid touching all of trans.
260+
bcx.with_block(|bcx| {
261+
let scratch = base::alloc_ty(bcx, ty, "drop");
262+
base::call_lifetime_start(bcx, scratch);
263+
build::Store(bcx, lvalue.llval, base::get_dataptr(bcx, scratch));
264+
build::Store(bcx, lvalue.llextra, base::get_meta(bcx, scratch));
265+
scratch
266+
})
249267
};
250268
if let Some(unwind) = unwind {
251269
bcx.invoke(drop_fn,

src/test/run-pass/issue-35546.rs

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Regression test for #35546. Check that we are able to codegen
12+
// this. Before we had problems because of the drop glue signature
13+
// around dropping a trait object (specifically, when dropping the
14+
// `value` field of `Node<Send>`).
15+
16+
struct Node<T: ?Sized + Send> {
17+
next: Option<Box<Node<Send>>>,
18+
value: T,
19+
}
20+
21+
fn clear(head: &mut Option<Box<Node<Send>>>) {
22+
match head.take() {
23+
Some(node) => *head = node.next,
24+
None => (),
25+
}
26+
}
27+
28+
fn main() {}

0 commit comments

Comments
 (0)