Skip to content

Commit 5d00b8a

Browse files
committed
rustc_trans: load C-like enums larger than usize from memory with -Zorbit.
1 parent 90ba77a commit 5d00b8a

File tree

1 file changed

+33
-25
lines changed

1 file changed

+33
-25
lines changed

src/librustc_trans/mir/rvalue.rs

+33-25
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,46 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
244244
}
245245
}
246246
}
247-
mir::CastKind::Misc if common::type_is_immediate(bcx.ccx(), operand.ty) => {
247+
mir::CastKind::Misc if common::type_is_fat_ptr(bcx.tcx(), operand.ty) => {
248+
let ll_cast_ty = type_of::immediate_type_of(bcx.ccx(), cast_ty);
249+
let ll_from_ty = type_of::immediate_type_of(bcx.ccx(), operand.ty);
250+
if let OperandValue::Pair(data_ptr, meta_ptr) = operand.val {
251+
if common::type_is_fat_ptr(bcx.tcx(), cast_ty) {
252+
let ll_cft = ll_cast_ty.field_types();
253+
let ll_fft = ll_from_ty.field_types();
254+
let data_cast = bcx.pointercast(data_ptr, ll_cft[0]);
255+
assert_eq!(ll_cft[1].kind(), ll_fft[1].kind());
256+
OperandValue::Pair(data_cast, meta_ptr)
257+
} else { // cast to thin-ptr
258+
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
259+
// pointer-cast of that pointer to desired pointer type.
260+
let llval = bcx.pointercast(data_ptr, ll_cast_ty);
261+
OperandValue::Immediate(llval)
262+
}
263+
} else {
264+
bug!("Unexpected non-Pair operand")
265+
}
266+
}
267+
mir::CastKind::Misc => {
248268
debug_assert!(common::type_is_immediate(bcx.ccx(), cast_ty));
249269
let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast");
250270
let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
251271
let ll_t_in = type_of::immediate_type_of(bcx.ccx(), operand.ty);
252272
let ll_t_out = type_of::immediate_type_of(bcx.ccx(), cast_ty);
253-
let llval = operand.immediate();
254-
let signed = if let CastTy::Int(IntTy::CEnum) = r_t_in {
273+
let (llval, signed) = if let CastTy::Int(IntTy::CEnum) = r_t_in {
255274
let repr = adt::represent_type(bcx.ccx(), operand.ty);
256-
adt::is_discr_signed(&repr)
275+
let discr = match operand.val {
276+
OperandValue::Immediate(llval) => llval,
277+
OperandValue::Ref(llptr) => {
278+
bcx.with_block(|bcx| {
279+
adt::trans_get_discr(bcx, &repr, llptr, None, true)
280+
})
281+
}
282+
OperandValue::Pair(..) => bug!("Unexpected Pair operand")
283+
};
284+
(discr, adt::is_discr_signed(&repr))
257285
} else {
258-
operand.ty.is_signed()
286+
(operand.immediate(), operand.ty.is_signed())
259287
};
260288

261289
let newval = match (r_t_in, r_t_out) {
@@ -304,26 +332,6 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
304332
};
305333
OperandValue::Immediate(newval)
306334
}
307-
mir::CastKind::Misc => { // Casts from a fat-ptr.
308-
let ll_cast_ty = type_of::immediate_type_of(bcx.ccx(), cast_ty);
309-
let ll_from_ty = type_of::immediate_type_of(bcx.ccx(), operand.ty);
310-
if let OperandValue::Pair(data_ptr, meta_ptr) = operand.val {
311-
if common::type_is_fat_ptr(bcx.tcx(), cast_ty) {
312-
let ll_cft = ll_cast_ty.field_types();
313-
let ll_fft = ll_from_ty.field_types();
314-
let data_cast = bcx.pointercast(data_ptr, ll_cft[0]);
315-
assert_eq!(ll_cft[1].kind(), ll_fft[1].kind());
316-
OperandValue::Pair(data_cast, meta_ptr)
317-
} else { // cast to thin-ptr
318-
// Cast of fat-ptr to thin-ptr is an extraction of data-ptr and
319-
// pointer-cast of that pointer to desired pointer type.
320-
let llval = bcx.pointercast(data_ptr, ll_cast_ty);
321-
OperandValue::Immediate(llval)
322-
}
323-
} else {
324-
bug!("Unexpected non-Pair operand")
325-
}
326-
}
327335
};
328336
let operand = OperandRef {
329337
val: val,

0 commit comments

Comments
 (0)