1
Fork 0

Fix foreign type handling

This commit is contained in:
bjorn3 2019-09-14 17:53:36 +02:00
parent b267995f39
commit c34ada7cca
4 changed files with 27 additions and 24 deletions

View file

@ -365,6 +365,7 @@ fn trans_stmt<'tcx>(
Rvalue::Cast(CastKind::Misc, operand, to_ty) => {
let operand = trans_operand(fx, operand);
let from_ty = operand.layout().ty;
let to_ty = fx.monomorphize(to_ty);
fn is_fat_ptr<'tcx>(
fx: &FunctionCx<'_, 'tcx, impl Backend>,
@ -375,9 +376,7 @@ fn trans_stmt<'tcx>(
|ty::TypeAndMut {
ty: pointee_ty,
mutbl: _,
}| {
fx.layout_of(pointee_ty).is_unsized()
},
}| has_ptr_meta(fx.tcx, pointee_ty),
)
.unwrap_or(false)
}

View file

@ -60,11 +60,11 @@ pub fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types:
FloatTy::F64 => types::F64,
},
ty::FnPtr(_) => pointer_ty(tcx),
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) | ty::Ref(_, ty, _) => {
if ty.is_sized(tcx.at(DUMMY_SP), ParamEnv::reveal_all()) {
pointer_ty(tcx)
} else {
ty::RawPtr(TypeAndMut { ty: pointee_ty, mutbl: _ }) | ty::Ref(_, pointee_ty, _) => {
if has_ptr_meta(tcx, pointee_ty) {
return None;
} else {
pointer_ty(tcx)
}
}
ty::Param(_) => bug!("ty param {:?}", ty),
@ -72,6 +72,16 @@ pub fn clif_type_from_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<types:
})
}
/// Is a pointer to this type a fat ptr?
pub fn has_ptr_meta<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
let ptr_ty = tcx.mk_ptr(TypeAndMut { ty, mutbl: rustc::hir::Mutability::MutImmutable });
match &tcx.layout_of(ParamEnv::reveal_all().and(ptr_ty)).unwrap().abi {
Abi::Scalar(_) => false,
Abi::ScalarPair(_, _) => true,
abi => unreachable!("Abi of ptr to {:?} is {:?}???", ty, abi),
}
}
pub fn codegen_select(bcx: &mut FunctionBuilder, cond: Value, lhs: Value, rhs: Value) -> Value {
let lhs_ty = bcx.func.dfg.value_type(lhs);
let rhs_ty = bcx.func.dfg.value_type(rhs);

View file

@ -347,14 +347,9 @@ pub fn trans_ptr_binop<'tcx>(
in_lhs: CValue<'tcx>,
in_rhs: CValue<'tcx>,
) -> CValue<'tcx> {
let not_fat = match in_lhs.layout().ty.sty {
ty::RawPtr(TypeAndMut { ty, mutbl: _ }) => {
ty.is_sized(fx.tcx.at(DUMMY_SP), ParamEnv::reveal_all())
}
ty::FnPtr(..) => true,
_ => bug!("trans_ptr_binop on non ptr"),
};
if not_fat {
let pointee_ty = in_lhs.layout().ty.builtin_deref(true).unwrap().ty;
if !has_ptr_meta(fx.tcx, pointee_ty) {
match bin_op {
BinOp::Eq | BinOp::Lt | BinOp::Le | BinOp::Ne | BinOp::Ge | BinOp::Gt => {
let lhs = in_lhs.load_scalar(fx);
@ -364,7 +359,6 @@ pub fn trans_ptr_binop<'tcx>(
}
BinOp::Offset => {
let (base, offset) = (in_lhs, in_rhs.load_scalar(fx));
let pointee_ty = base.layout().ty.builtin_deref(true).unwrap().ty;
let pointee_size = fx.layout_of(pointee_ty).size.bytes();
let ptr_diff = fx.bcx.ins().imul_imm(offset, pointee_size as i64);
let base_val = base.load_scalar(fx);

View file

@ -136,7 +136,7 @@ impl<'tcx> CValue<'tcx> {
CValueInner::ByRef(addr) => {
let (a_scalar, b_scalar) = match &layout.abi {
layout::Abi::ScalarPair(a, b) => (a, b),
_ => unreachable!(),
_ => unreachable!("load_scalar_pair({:?})", self),
};
let b_offset = scalar_pair_calculate_b_offset(fx.tcx, a_scalar, b_scalar);
let clif_ty1 = scalar_to_clif_type(fx.tcx, a_scalar.clone());
@ -496,19 +496,16 @@ impl<'tcx> CPlace<'tcx> {
pub fn place_deref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>) -> CPlace<'tcx> {
let inner_layout = fx.layout_of(self.layout().ty.builtin_deref(true).unwrap().ty);
if !inner_layout.is_unsized() {
CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout)
} else {
if has_ptr_meta(fx.tcx, inner_layout.ty) {
let (addr, extra) = self.to_cvalue(fx).load_scalar_pair(fx);
CPlace::for_addr_with_extra(addr, extra, inner_layout)
} else {
CPlace::for_addr(self.to_cvalue(fx).load_scalar(fx), inner_layout)
}
}
pub fn write_place_ref(self, fx: &mut FunctionCx<'_, 'tcx, impl Backend>, dest: CPlace<'tcx>) {
if !self.layout().is_unsized() {
let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
dest.write_cvalue(fx, ptr);
} else {
if has_ptr_meta(fx.tcx, self.layout().ty) {
let (value, extra) = self.to_addr_maybe_unsized(fx);
let ptr = CValue::by_val_pair(
value,
@ -516,6 +513,9 @@ impl<'tcx> CPlace<'tcx> {
dest.layout(),
);
dest.write_cvalue(fx, ptr);
} else {
let ptr = CValue::by_val(self.to_addr(fx), dest.layout());
dest.write_cvalue(fx, ptr);
}
}