Skip to content

Commit 342bac9

Browse files
committed
Fix drop for dyn*
1 parent 2470ad3 commit 342bac9

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed

src/abi/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,7 @@ pub(crate) fn codegen_drop<'tcx>(
613613
// (data, vtable) // an equivalent Rust `*mut dyn Trait`
614614
//
615615
// SO THEN WE CAN USE THE ABOVE CODE.
616-
let dyn_star = drop_place.to_cvalue(fx);
617-
let (data, vtable) = dyn_star.load_scalar_pair(fx);
616+
let (data, vtable) = drop_place.to_cvalue(fx).dyn_star_force_data_on_stack(fx);
618617
let drop_fn = crate::vtable::drop_fn_of_obj(fx, vtable);
619618

620619
let virtual_drop = Instance {

src/value_and_place.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,50 @@ impl<'tcx> CValue<'tcx> {
107107
}
108108
}
109109

110+
// FIXME remove
111+
// Forces the data value of a dyn* value to the stack and returns a pointer to it as well as the
112+
// vtable pointer.
113+
pub(crate) fn dyn_star_force_data_on_stack(
114+
self,
115+
fx: &mut FunctionCx<'_, '_, 'tcx>,
116+
) -> (Value, Value) {
117+
assert!(self.1.ty.is_dyn_star());
118+
119+
match self.0 {
120+
CValueInner::ByRef(ptr, None) => {
121+
let (a_scalar, b_scalar) = match self.1.abi {
122+
Abi::ScalarPair(a, b) => (a, b),
123+
_ => unreachable!("dyn_star_force_data_on_stack({:?})", self),
124+
};
125+
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
126+
let clif_ty2 = scalar_to_clif_type(fx.tcx, b_scalar);
127+
let mut flags = MemFlags::new();
128+
flags.set_notrap();
129+
let vtable = ptr.offset(fx, b_offset).load(fx, clif_ty2, flags);
130+
(ptr.get_addr(fx), vtable)
131+
}
132+
CValueInner::ByValPair(data, vtable) => {
133+
let stack_slot = fx.bcx.create_sized_stack_slot(StackSlotData {
134+
kind: StackSlotKind::ExplicitSlot,
135+
// FIXME Don't force the size to a multiple of 16 bytes once Cranelift gets a way to
136+
// specify stack slot alignment.
137+
size: (u32::try_from(fx.target_config.pointer_type().bytes()).unwrap() + 15)
138+
/ 16
139+
* 16,
140+
});
141+
let data_ptr = Pointer::stack_slot(stack_slot);
142+
let mut flags = MemFlags::new();
143+
flags.set_notrap();
144+
data_ptr.store(fx, data, flags);
145+
146+
(data_ptr.get_addr(fx), vtable)
147+
}
148+
CValueInner::ByRef(_, Some(_)) | CValueInner::ByVal(_) => {
149+
unreachable!("dyn_star_force_data_on_stack({:?})", self)
150+
}
151+
}
152+
}
153+
110154
pub(crate) fn try_to_ptr(self) -> Option<(Pointer, Option<Value>)> {
111155
match self.0 {
112156
CValueInner::ByRef(ptr, meta) => Some((ptr, meta)),

0 commit comments

Comments
 (0)