]> git.lizzy.rs Git - rust.git/commitdiff
rustc_trans: load C-like enums larger than usize from memory with -Zorbit.
authorEduard Burtescu <edy.burt@gmail.com>
Tue, 2 Aug 2016 00:28:50 +0000 (03:28 +0300)
committerEduard Burtescu <edy.burt@gmail.com>
Tue, 2 Aug 2016 06:01:47 +0000 (09:01 +0300)
src/librustc_trans/mir/rvalue.rs

index 6ebc23884918976c19f4cfc1c220ed3ab3977a8f..97d65ce9c53614bf1a2600fd48e6c0fb1f15f3cc 100644 (file)
@@ -244,18 +244,46 @@ pub fn trans_rvalue_operand(&mut self,
                             }
                         }
                     }
-                    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 @@ pub fn trans_rvalue_operand(&mut self,
                         };
                         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,