diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2016-08-02 03:28:50 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2016-08-02 09:01:47 +0300 |
| commit | 5d00b8aa065b2da826613d9beda75657cec3f87d (patch) | |
| tree | 550be978863c5c612162a1d0c3025980f89408ee /src | |
| parent | 90ba77a7a9807a3a463f2820a4e652052e32efa0 (diff) | |
| download | rust-5d00b8aa065b2da826613d9beda75657cec3f87d.tar.gz rust-5d00b8aa065b2da826613d9beda75657cec3f87d.zip | |
rustc_trans: load C-like enums larger than usize from memory with -Zorbit.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_trans/mir/rvalue.rs | 58 |
1 files changed, 33 insertions, 25 deletions
diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 6ebc2388491..97d65ce9c53 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -244,18 +244,46 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { } } } - mir::CastKind::Misc if common::type_is_immediate(bcx.ccx(), operand.ty) => { + mir::CastKind::Misc if common::type_is_fat_ptr(bcx.tcx(), operand.ty) => { + let ll_cast_ty = type_of::immediate_type_of(bcx.ccx(), cast_ty); + let ll_from_ty = type_of::immediate_type_of(bcx.ccx(), operand.ty); + if let OperandValue::Pair(data_ptr, meta_ptr) = operand.val { + if common::type_is_fat_ptr(bcx.tcx(), cast_ty) { + let ll_cft = ll_cast_ty.field_types(); + let ll_fft = ll_from_ty.field_types(); + let data_cast = bcx.pointercast(data_ptr, ll_cft[0]); + assert_eq!(ll_cft[1].kind(), ll_fft[1].kind()); + OperandValue::Pair(data_cast, meta_ptr) + } else { // cast to thin-ptr + // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and + // pointer-cast of that pointer to desired pointer type. + let llval = bcx.pointercast(data_ptr, ll_cast_ty); + OperandValue::Immediate(llval) + } + } else { + bug!("Unexpected non-Pair operand") + } + } + mir::CastKind::Misc => { debug_assert!(common::type_is_immediate(bcx.ccx(), cast_ty)); let r_t_in = CastTy::from_ty(operand.ty).expect("bad input type for cast"); let r_t_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); let ll_t_in = type_of::immediate_type_of(bcx.ccx(), operand.ty); let ll_t_out = type_of::immediate_type_of(bcx.ccx(), cast_ty); - let llval = operand.immediate(); - let signed = if let CastTy::Int(IntTy::CEnum) = r_t_in { + let (llval, signed) = if let CastTy::Int(IntTy::CEnum) = r_t_in { let repr = adt::represent_type(bcx.ccx(), operand.ty); - adt::is_discr_signed(&repr) + let discr = match operand.val { + OperandValue::Immediate(llval) => llval, + OperandValue::Ref(llptr) => { + bcx.with_block(|bcx| { + adt::trans_get_discr(bcx, &repr, llptr, None, true) + }) + } + OperandValue::Pair(..) => bug!("Unexpected Pair operand") + }; + (discr, adt::is_discr_signed(&repr)) } else { - operand.ty.is_signed() + (operand.immediate(), operand.ty.is_signed()) }; let newval = match (r_t_in, r_t_out) { @@ -304,26 +332,6 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { }; OperandValue::Immediate(newval) } - mir::CastKind::Misc => { // Casts from a fat-ptr. - let ll_cast_ty = type_of::immediate_type_of(bcx.ccx(), cast_ty); - let ll_from_ty = type_of::immediate_type_of(bcx.ccx(), operand.ty); - if let OperandValue::Pair(data_ptr, meta_ptr) = operand.val { - if common::type_is_fat_ptr(bcx.tcx(), cast_ty) { - let ll_cft = ll_cast_ty.field_types(); - let ll_fft = ll_from_ty.field_types(); - let data_cast = bcx.pointercast(data_ptr, ll_cft[0]); - assert_eq!(ll_cft[1].kind(), ll_fft[1].kind()); - OperandValue::Pair(data_cast, meta_ptr) - } else { // cast to thin-ptr - // Cast of fat-ptr to thin-ptr is an extraction of data-ptr and - // pointer-cast of that pointer to desired pointer type. - let llval = bcx.pointercast(data_ptr, ll_cast_ty); - OperandValue::Immediate(llval) - } - } else { - bug!("Unexpected non-Pair operand") - } - } }; let operand = OperandRef { val: val, |
