diff options
| author | Anthony Ramine <n.oxyde@gmail.com> | 2018-04-11 17:25:18 +0200 |
|---|---|---|
| committer | Anthony Ramine <n.oxyde@gmail.com> | 2018-04-26 15:07:04 +0200 |
| commit | b7c8cc4b778b2fcf4193a3f7fd9cf8c323ebcf5c (patch) | |
| tree | 1226d542d47a193c17c263b2bb5ac78737a2eb5b | |
| parent | 3eca70a0c55e9f081ebff9a7af6fa25390d99b4c (diff) | |
| download | rust-b7c8cc4b778b2fcf4193a3f7fd9cf8c323ebcf5c.tar.gz rust-b7c8cc4b778b2fcf4193a3f7fd9cf8c323ebcf5c.zip | |
Properly look for uninhabitedness when handling discriminants
| -rw-r--r-- | src/librustc_mir/interpret/eval_context.rs | 3 | ||||
| -rw-r--r-- | src/librustc_trans/mir/place.rs | 5 | ||||
| -rw-r--r-- | src/librustc_trans/mir/rvalue.rs | 10 |
3 files changed, 15 insertions, 3 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index b98ab218de5..478f45e841d 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -850,6 +850,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M ) -> EvalResult<'tcx, u128> { let layout = self.layout_of(ty)?; trace!("read_discriminant_value {:#?}", layout); + if layout.abi == layout::Abi::Uninhabited { + return Ok(0); + } match layout.variants { layout::Variants::Single { index } => { diff --git a/src/librustc_trans/mir/place.rs b/src/librustc_trans/mir/place.rs index b340d91b027..3cadaef47bb 100644 --- a/src/librustc_trans/mir/place.rs +++ b/src/librustc_trans/mir/place.rs @@ -16,7 +16,7 @@ use rustc::mir::tcx::PlaceTy; use rustc_data_structures::indexed_vec::Idx; use base; use builder::Builder; -use common::{CodegenCx, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big}; +use common::{CodegenCx, C_undef, C_usize, C_u8, C_u32, C_uint, C_int, C_null, C_uint_big}; use consts; use type_of::LayoutLlvmExt; use type_::Type; @@ -264,6 +264,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> { /// Obtain the actual discriminant of a value. pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx); + if self.layout.abi == layout::Abi::Uninhabited { + return C_undef(cast_to); + } match self.layout.variants { layout::Variants::Single { index } => { return C_uint(cast_to, index as u64); diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs index 93702bfbbf3..245f3ec11c9 100644 --- a/src/librustc_trans/mir/rvalue.rs +++ b/src/librustc_trans/mir/rvalue.rs @@ -22,7 +22,7 @@ use base; use builder::Builder; use callee; use common::{self, val_ty}; -use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_null, C_usize, C_uint, C_uint_big}; +use common::{C_bool, C_u8, C_i32, C_u32, C_u64, C_undef, C_null, C_usize, C_uint, C_uint_big}; use consts; use monomorphize; use type_::Type; @@ -267,11 +267,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> { } mir::CastKind::Misc => { assert!(cast.is_llvm_immediate()); + let ll_t_out = cast.immediate_llvm_type(bx.cx); + if operand.layout.abi == layout::Abi::Uninhabited { + return (bx, OperandRef { + val: OperandValue::Immediate(C_undef(ll_t_out)), + layout: cast, + }); + } let r_t_in = CastTy::from_ty(operand.layout.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 = operand.layout.immediate_llvm_type(bx.cx); - let ll_t_out = cast.immediate_llvm_type(bx.cx); let llval = operand.immediate(); let mut signed = false; |
