1
Fork 0

Properly look for uninhabitedness when handling discriminants

This commit is contained in:
Anthony Ramine 2018-04-11 17:25:18 +02:00
parent 3eca70a0c5
commit b7c8cc4b77
3 changed files with 15 additions and 3 deletions

View file

@ -850,6 +850,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
) -> EvalResult<'tcx, u128> { ) -> EvalResult<'tcx, u128> {
let layout = self.layout_of(ty)?; let layout = self.layout_of(ty)?;
trace!("read_discriminant_value {:#?}", layout); trace!("read_discriminant_value {:#?}", layout);
if layout.abi == layout::Abi::Uninhabited {
return Ok(0);
}
match layout.variants { match layout.variants {
layout::Variants::Single { index } => { layout::Variants::Single { index } => {

View file

@ -16,7 +16,7 @@ use rustc::mir::tcx::PlaceTy;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use base; use base;
use builder::Builder; 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 consts;
use type_of::LayoutLlvmExt; use type_of::LayoutLlvmExt;
use type_::Type; use type_::Type;
@ -264,6 +264,9 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
/// Obtain the actual discriminant of a value. /// Obtain the actual discriminant of a value.
pub fn trans_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef { 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); 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 { match self.layout.variants {
layout::Variants::Single { index } => { layout::Variants::Single { index } => {
return C_uint(cast_to, index as u64); return C_uint(cast_to, index as u64);

View file

@ -22,7 +22,7 @@ use base;
use builder::Builder; use builder::Builder;
use callee; use callee;
use common::{self, val_ty}; 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 consts;
use monomorphize; use monomorphize;
use type_::Type; use type_::Type;
@ -267,11 +267,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
} }
mir::CastKind::Misc => { mir::CastKind::Misc => {
assert!(cast.is_llvm_immediate()); 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) let r_t_in = CastTy::from_ty(operand.layout.ty)
.expect("bad input type for cast"); .expect("bad input type for cast");
let r_t_out = CastTy::from_ty(cast.ty).expect("bad output 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_in = operand.layout.immediate_llvm_type(bx.cx);
let ll_t_out = cast.immediate_llvm_type(bx.cx);
let llval = operand.immediate(); let llval = operand.immediate();
let mut signed = false; let mut signed = false;