rustc: move CEnum's signedness into Primitive::Int.
This commit is contained in:
parent
61c2bd9ca4
commit
d318b9c27b
8 changed files with 65 additions and 80 deletions
|
@ -498,7 +498,7 @@ impl<'a, 'tcx> Integer {
|
||||||
|
|
||||||
let wanted = align.abi();
|
let wanted = align.abi();
|
||||||
for &candidate in &[I8, I16, I32, I64] {
|
for &candidate in &[I8, I16, I32, I64] {
|
||||||
let ty = Int(candidate);
|
let ty = Int(candidate, false);
|
||||||
if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
|
if wanted == ty.align(dl).abi() && wanted == ty.size(dl).bytes() {
|
||||||
return Some(candidate);
|
return Some(candidate);
|
||||||
}
|
}
|
||||||
|
@ -577,7 +577,14 @@ impl<'a, 'tcx> Integer {
|
||||||
/// Fundamental unit of memory access and layout.
|
/// Fundamental unit of memory access and layout.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||||
pub enum Primitive {
|
pub enum Primitive {
|
||||||
Int(Integer),
|
/// The `bool` is the signedness of the `Integer` type.
|
||||||
|
///
|
||||||
|
/// One would think we would not care about such details this low down,
|
||||||
|
/// but some ABIs are described in terms of C types and ISAs where the
|
||||||
|
/// integer arithmetic is done on {sign,zero}-extended registers, e.g.
|
||||||
|
/// a negative integer passed by zero-extension will appear positive in
|
||||||
|
/// the callee, and most operations on it will produce the wrong values.
|
||||||
|
Int(Integer, bool),
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
Pointer
|
Pointer
|
||||||
|
@ -588,11 +595,9 @@ impl<'a, 'tcx> Primitive {
|
||||||
let dl = cx.data_layout();
|
let dl = cx.data_layout();
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Int(I1) | Int(I8) => Size::from_bits(8),
|
Int(i, _) => i.size(),
|
||||||
Int(I16) => Size::from_bits(16),
|
F32 => Size::from_bits(32),
|
||||||
Int(I32) | F32 => Size::from_bits(32),
|
F64 => Size::from_bits(64),
|
||||||
Int(I64) | F64 => Size::from_bits(64),
|
|
||||||
Int(I128) => Size::from_bits(128),
|
|
||||||
Pointer => dl.pointer_size
|
Pointer => dl.pointer_size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -601,12 +606,7 @@ impl<'a, 'tcx> Primitive {
|
||||||
let dl = cx.data_layout();
|
let dl = cx.data_layout();
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
Int(I1) => dl.i1_align,
|
Int(i, _) => i.align(dl),
|
||||||
Int(I8) => dl.i8_align,
|
|
||||||
Int(I16) => dl.i16_align,
|
|
||||||
Int(I32) => dl.i32_align,
|
|
||||||
Int(I64) => dl.i64_align,
|
|
||||||
Int(I128) => dl.i128_align,
|
|
||||||
F32 => dl.f32_align,
|
F32 => dl.f32_align,
|
||||||
F64 => dl.f64_align,
|
F64 => dl.f64_align,
|
||||||
Pointer => dl.pointer_align
|
Pointer => dl.pointer_align
|
||||||
|
@ -615,7 +615,7 @@ impl<'a, 'tcx> Primitive {
|
||||||
|
|
||||||
pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
|
pub fn to_ty(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Ty<'tcx> {
|
||||||
match *self {
|
match *self {
|
||||||
Int(i) => i.to_ty(tcx, false),
|
Int(i, signed) => i.to_ty(tcx, signed),
|
||||||
F32 => tcx.types.f32,
|
F32 => tcx.types.f32,
|
||||||
F64 => tcx.types.f64,
|
F64 => tcx.types.f64,
|
||||||
Pointer => tcx.mk_mut_ptr(tcx.mk_nil()),
|
Pointer => tcx.mk_mut_ptr(tcx.mk_nil()),
|
||||||
|
@ -1098,7 +1098,6 @@ pub enum Layout {
|
||||||
/// C-like enums; basically an integer.
|
/// C-like enums; basically an integer.
|
||||||
CEnum {
|
CEnum {
|
||||||
discr: Primitive,
|
discr: Primitive,
|
||||||
signed: bool,
|
|
||||||
/// Inclusive discriminant range.
|
/// Inclusive discriminant range.
|
||||||
/// If min > max, it represents min...u64::MAX followed by 0...max.
|
/// If min > max, it represents min...u64::MAX followed by 0...max.
|
||||||
// FIXME(eddyb) always use the shortest range, e.g. by finding
|
// FIXME(eddyb) always use the shortest range, e.g. by finding
|
||||||
|
@ -1287,7 +1286,7 @@ impl<'a, 'tcx> Layout {
|
||||||
let metadata = match unsized_part.sty {
|
let metadata = match unsized_part.sty {
|
||||||
ty::TyForeign(..) => return Ok(Scalar(Pointer)),
|
ty::TyForeign(..) => return Ok(Scalar(Pointer)),
|
||||||
ty::TySlice(_) | ty::TyStr => {
|
ty::TySlice(_) | ty::TyStr => {
|
||||||
Int(dl.ptr_sized_integer())
|
Int(dl.ptr_sized_integer(), false)
|
||||||
}
|
}
|
||||||
ty::TyDynamic(..) => Pointer,
|
ty::TyDynamic(..) => Pointer,
|
||||||
_ => return Err(LayoutError::Unknown(unsized_part))
|
_ => return Err(LayoutError::Unknown(unsized_part))
|
||||||
|
@ -1298,13 +1297,13 @@ impl<'a, 'tcx> Layout {
|
||||||
|
|
||||||
let layout = match ty.sty {
|
let layout = match ty.sty {
|
||||||
// Basic scalars.
|
// Basic scalars.
|
||||||
ty::TyBool => Scalar(Int(I1)),
|
ty::TyBool => Scalar(Int(I1, false)),
|
||||||
ty::TyChar => Scalar(Int(I32)),
|
ty::TyChar => Scalar(Int(I32, false)),
|
||||||
ty::TyInt(ity) => {
|
ty::TyInt(ity) => {
|
||||||
Scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity))))
|
Scalar(Int(Integer::from_attr(dl, attr::SignedInt(ity)), true))
|
||||||
}
|
}
|
||||||
ty::TyUint(ity) => {
|
ty::TyUint(ity) => {
|
||||||
Scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity))))
|
Scalar(Int(Integer::from_attr(dl, attr::UnsignedInt(ity)), false))
|
||||||
}
|
}
|
||||||
ty::TyFloat(FloatTy::F32) => Scalar(F32),
|
ty::TyFloat(FloatTy::F32) => Scalar(F32),
|
||||||
ty::TyFloat(FloatTy::F64) => Scalar(F64),
|
ty::TyFloat(FloatTy::F64) => Scalar(F64),
|
||||||
|
@ -1453,8 +1452,7 @@ impl<'a, 'tcx> Layout {
|
||||||
// grok.
|
// grok.
|
||||||
let (discr, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
|
let (discr, signed) = Integer::repr_discr(tcx, ty, &def.repr, min, max);
|
||||||
return success(CEnum {
|
return success(CEnum {
|
||||||
discr: Int(discr),
|
discr: Int(discr, signed),
|
||||||
signed,
|
|
||||||
// FIXME: should be u128?
|
// FIXME: should be u128?
|
||||||
min: min as u64,
|
min: min as u64,
|
||||||
max: max as u64
|
max: max as u64
|
||||||
|
@ -1629,8 +1627,8 @@ impl<'a, 'tcx> Layout {
|
||||||
ity = min_ity;
|
ity = min_ity;
|
||||||
} else {
|
} else {
|
||||||
// Patch up the variants' first few fields.
|
// Patch up the variants' first few fields.
|
||||||
let old_ity_size = Int(min_ity).size(dl);
|
let old_ity_size = min_ity.size();
|
||||||
let new_ity_size = Int(ity).size(dl);
|
let new_ity_size = ity.size();
|
||||||
for variant in &mut variants {
|
for variant in &mut variants {
|
||||||
for i in variant.offsets.iter_mut() {
|
for i in variant.offsets.iter_mut() {
|
||||||
if *i <= old_ity_size {
|
if *i <= old_ity_size {
|
||||||
|
@ -1646,7 +1644,7 @@ impl<'a, 'tcx> Layout {
|
||||||
}
|
}
|
||||||
|
|
||||||
General {
|
General {
|
||||||
discr: Int(ity),
|
discr: Int(ity, false),
|
||||||
variants,
|
variants,
|
||||||
size,
|
size,
|
||||||
align,
|
align,
|
||||||
|
@ -2417,9 +2415,8 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for Layout
|
||||||
FatPointer(ref metadata) => {
|
FatPointer(ref metadata) => {
|
||||||
metadata.hash_stable(hcx, hasher);
|
metadata.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
CEnum { discr, signed, min, max } => {
|
CEnum { discr, min, max } => {
|
||||||
discr.hash_stable(hcx, hasher);
|
discr.hash_stable(hcx, hasher);
|
||||||
signed.hash_stable(hcx, hasher);
|
|
||||||
min.hash_stable(hcx, hasher);
|
min.hash_stable(hcx, hasher);
|
||||||
max.hash_stable(hcx, hasher);
|
max.hash_stable(hcx, hasher);
|
||||||
}
|
}
|
||||||
|
@ -2505,7 +2502,7 @@ impl_stable_hash_for!(enum ::ty::layout::Integer {
|
||||||
});
|
});
|
||||||
|
|
||||||
impl_stable_hash_for!(enum ::ty::layout::Primitive {
|
impl_stable_hash_for!(enum ::ty::layout::Primitive {
|
||||||
Int(integer),
|
Int(integer, signed),
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
Pointer
|
Pointer
|
||||||
|
|
|
@ -288,7 +288,7 @@ impl<'tcx> LayoutExt<'tcx> for FullLayout<'tcx> {
|
||||||
// The primitive for this algorithm.
|
// The primitive for this algorithm.
|
||||||
layout::Abi::Scalar(value) => {
|
layout::Abi::Scalar(value) => {
|
||||||
let kind = match value {
|
let kind = match value {
|
||||||
layout::Int(_) |
|
layout::Int(..) |
|
||||||
layout::Pointer => RegKind::Integer,
|
layout::Pointer => RegKind::Integer,
|
||||||
layout::F32 |
|
layout::F32 |
|
||||||
layout::F64 => RegKind::Float
|
layout::F64 => RegKind::Float
|
||||||
|
@ -467,18 +467,8 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
||||||
|
|
||||||
pub fn extend_integer_width_to(&mut self, bits: u64) {
|
pub fn extend_integer_width_to(&mut self, bits: u64) {
|
||||||
// Only integers have signedness
|
// Only integers have signedness
|
||||||
let (i, signed) = match *self.layout {
|
match self.layout.abi {
|
||||||
Layout::Scalar(layout::Int(i)) if self.layout.ty.is_integral() => {
|
layout::Abi::Scalar(layout::Int(i, signed)) => {
|
||||||
(i, self.layout.ty.is_signed())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rust enum types that map onto C enums also need to follow
|
|
||||||
// the target ABI zero-/sign-extension rules.
|
|
||||||
Layout::CEnum { discr: layout::Int(i), signed, .. } => (i, signed),
|
|
||||||
|
|
||||||
_ => return
|
|
||||||
};
|
|
||||||
|
|
||||||
if i.size().bits() < bits {
|
if i.size().bits() < bits {
|
||||||
self.attrs.set(if signed {
|
self.attrs.set(if signed {
|
||||||
ArgAttribute::SExt
|
ArgAttribute::SExt
|
||||||
|
@ -488,6 +478,10 @@ impl<'a, 'tcx> ArgType<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) {
|
pub fn cast_to<T: Into<CastTarget>>(&mut self, target: T) {
|
||||||
self.cast = Some(target.into());
|
self.cast = Some(target.into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,9 +230,3 @@ pub fn struct_llfields<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_discr_signed<'tcx>(l: &layout::Layout) -> bool {
|
|
||||||
match *l {
|
|
||||||
layout::CEnum { signed, .. }=> signed,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ fn classify_arg<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, arg: &ArgType<'tcx>)
|
||||||
match layout.abi {
|
match layout.abi {
|
||||||
layout::Abi::Scalar(value) => {
|
layout::Abi::Scalar(value) => {
|
||||||
let reg = match value {
|
let reg = match value {
|
||||||
layout::Int(_) |
|
layout::Int(..) |
|
||||||
layout::Pointer => Class::Int,
|
layout::Pointer => Class::Int,
|
||||||
layout::F32 |
|
layout::F32 |
|
||||||
layout::F64 => Class::Sse
|
layout::F64 => Class::Sse
|
||||||
|
|
|
@ -1451,7 +1451,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let discriminant_type_metadata = |discr: layout::Primitive, signed: bool| {
|
let discriminant_type_metadata = |discr: layout::Primitive| {
|
||||||
let disr_type_key = (enum_def_id, discr);
|
let disr_type_key = (enum_def_id, discr);
|
||||||
let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
|
let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
|
||||||
.borrow()
|
.borrow()
|
||||||
|
@ -1462,12 +1462,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
let (discriminant_size, discriminant_align) =
|
let (discriminant_size, discriminant_align) =
|
||||||
(discr.size(cx), discr.align(cx));
|
(discr.size(cx), discr.align(cx));
|
||||||
let discriminant_base_type_metadata =
|
let discriminant_base_type_metadata =
|
||||||
type_metadata(cx,
|
type_metadata(cx, discr.to_ty(cx.tcx()), syntax_pos::DUMMY_SP);
|
||||||
match discr {
|
|
||||||
layout::Int(i) => i.to_ty(cx.tcx(), signed),
|
|
||||||
_ => discr.to_ty(cx.tcx())
|
|
||||||
},
|
|
||||||
syntax_pos::DUMMY_SP);
|
|
||||||
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
|
let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
|
||||||
|
|
||||||
let name = CString::new(discriminant_name.as_bytes()).unwrap();
|
let name = CString::new(discriminant_name.as_bytes()).unwrap();
|
||||||
|
@ -1496,11 +1491,11 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||||
let type_rep = cx.layout_of(enum_type);
|
let type_rep = cx.layout_of(enum_type);
|
||||||
|
|
||||||
let discriminant_type_metadata = match *type_rep {
|
let discriminant_type_metadata = match *type_rep {
|
||||||
layout::CEnum { discr, signed, .. } => {
|
layout::CEnum { discr, .. } => {
|
||||||
return FinalMetadata(discriminant_type_metadata(discr, signed))
|
return FinalMetadata(discriminant_type_metadata(discr))
|
||||||
},
|
},
|
||||||
layout::NullablePointer { .. } | layout::Univariant { .. } => None,
|
layout::NullablePointer { .. } | layout::Univariant { .. } => None,
|
||||||
layout::General { discr, .. } => Some(discriminant_type_metadata(discr, false)),
|
layout::General { discr, .. } => Some(discriminant_type_metadata(discr)),
|
||||||
ref l @ _ => bug!("Not an enum layout: {:#?}", l)
|
ref l @ _ => bug!("Not an enum layout: {:#?}", l)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ use rustc::ty::cast::{CastTy, IntTy};
|
||||||
use rustc::ty::subst::{Kind, Substs, Subst};
|
use rustc::ty::subst::{Kind, Substs, Subst};
|
||||||
use rustc_apfloat::{ieee, Float, Status};
|
use rustc_apfloat::{ieee, Float, Status};
|
||||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||||
use {adt, base};
|
use base;
|
||||||
use abi::{self, Abi};
|
use abi::{self, Abi};
|
||||||
use callee;
|
use callee;
|
||||||
use builder::Builder;
|
use builder::Builder;
|
||||||
|
@ -683,11 +683,9 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
|
||||||
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_out = self.ccx.immediate_llvm_type_of(cast_ty);
|
let ll_t_out = self.ccx.immediate_llvm_type_of(cast_ty);
|
||||||
let llval = operand.llval;
|
let llval = operand.llval;
|
||||||
let signed = if let CastTy::Int(IntTy::CEnum) = r_t_in {
|
let signed = match self.ccx.layout_of(operand.ty).abi {
|
||||||
let l = self.ccx.layout_of(operand.ty);
|
layout::Abi::Scalar(layout::Int(_, signed)) => signed,
|
||||||
adt::is_discr_signed(&l)
|
_ => false
|
||||||
} else {
|
|
||||||
operand.ty.is_signed()
|
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
@ -352,7 +352,7 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
|
|
||||||
/// Helper for cases where the discriminant is simply loaded.
|
/// Helper for cases where the discriminant is simply loaded.
|
||||||
fn load_discr(self, bcx: &Builder, discr: layout::Primitive, min: u64, max: u64) -> ValueRef {
|
fn load_discr(self, bcx: &Builder, discr: layout::Primitive, min: u64, max: u64) -> ValueRef {
|
||||||
if let layout::Int(ity) = discr {
|
if let layout::Int(ity, _) = discr {
|
||||||
let bits = ity.size().bits();
|
let bits = ity.size().bits();
|
||||||
assert!(bits <= 64);
|
assert!(bits <= 64);
|
||||||
let bits = bits as usize;
|
let bits = bits as usize;
|
||||||
|
@ -380,25 +380,30 @@ impl<'a, 'tcx> LvalueRef<'tcx> {
|
||||||
let l = bcx.ccx.layout_of(self.ty.to_ty(bcx.tcx()));
|
let l = bcx.ccx.layout_of(self.ty.to_ty(bcx.tcx()));
|
||||||
|
|
||||||
let cast_to = bcx.ccx.immediate_llvm_type_of(cast_to);
|
let cast_to = bcx.ccx.immediate_llvm_type_of(cast_to);
|
||||||
let val = match *l {
|
let (val, discr) = match *l {
|
||||||
layout::Univariant { .. } |
|
layout::Univariant { .. } |
|
||||||
layout::UntaggedUnion { .. } => return C_uint(cast_to, 0),
|
layout::UntaggedUnion { .. } => return C_uint(cast_to, 0),
|
||||||
layout::CEnum { discr, min, max, .. } => {
|
layout::CEnum { discr, min, max, .. } => {
|
||||||
self.load_discr(bcx, discr, min, max)
|
(self.load_discr(bcx, discr, min, max), discr)
|
||||||
}
|
}
|
||||||
layout::General { discr, ref variants, .. } => {
|
layout::General { discr, ref variants, .. } => {
|
||||||
let ptr = self.project_field(bcx, 0);
|
let ptr = self.project_field(bcx, 0);
|
||||||
ptr.load_discr(bcx, discr, 0, variants.len() as u64 - 1)
|
(ptr.load_discr(bcx, discr, 0, variants.len() as u64 - 1), discr)
|
||||||
}
|
}
|
||||||
layout::NullablePointer { nndiscr, .. } => {
|
layout::NullablePointer { nndiscr, .. } => {
|
||||||
let ptr = self.project_field(bcx, 0);
|
let ptr = self.project_field(bcx, 0);
|
||||||
let lldiscr = bcx.load(ptr.llval, ptr.alignment.non_abi());
|
let lldiscr = bcx.load(ptr.llval, ptr.alignment.non_abi());
|
||||||
let cmp = if nndiscr == 0 { llvm::IntEQ } else { llvm::IntNE };
|
let cmp = if nndiscr == 0 { llvm::IntEQ } else { llvm::IntNE };
|
||||||
bcx.icmp(cmp, lldiscr, C_null(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx()))))
|
(bcx.icmp(cmp, lldiscr, C_null(bcx.ccx.llvm_type_of(ptr.ty.to_ty(bcx.tcx())))),
|
||||||
|
layout::Int(layout::I1, false))
|
||||||
},
|
},
|
||||||
_ => bug!("{} is not an enum", l.ty)
|
_ => bug!("{} is not an enum", l.ty)
|
||||||
};
|
};
|
||||||
bcx.intcast(val, cast_to, adt::is_discr_signed(&l))
|
let signed = match discr {
|
||||||
|
layout::Int(_, signed) => signed,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
bcx.intcast(val, cast_to, signed)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the discriminant for a new value of the given case of the given
|
/// Set the discriminant for a new value of the given case of the given
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use llvm::{self, ValueRef};
|
use llvm::{self, ValueRef};
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::cast::{CastTy, IntTy};
|
use rustc::ty::cast::{CastTy, IntTy};
|
||||||
use rustc::ty::layout::{Layout, LayoutOf};
|
use rustc::ty::layout::{self, Layout, LayoutOf};
|
||||||
use rustc::mir;
|
use rustc::mir;
|
||||||
use rustc::middle::lang_items::ExchangeMallocFnLangItem;
|
use rustc::middle::lang_items::ExchangeMallocFnLangItem;
|
||||||
use rustc_apfloat::{ieee, Float, Status, Round};
|
use rustc_apfloat::{ieee, Float, Status, Round};
|
||||||
|
@ -276,7 +276,8 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
let ll_t_out = bcx.ccx.immediate_llvm_type_of(cast_ty);
|
let ll_t_out = bcx.ccx.immediate_llvm_type_of(cast_ty);
|
||||||
let llval = operand.immediate();
|
let llval = operand.immediate();
|
||||||
let l = bcx.ccx.layout_of(operand.ty);
|
let l = bcx.ccx.layout_of(operand.ty);
|
||||||
let signed = if let Layout::CEnum { signed, min, max, .. } = *l {
|
|
||||||
|
if let Layout::CEnum { min, max, .. } = *l {
|
||||||
if max > min {
|
if max > min {
|
||||||
// We want `table[e as usize]` to not
|
// We want `table[e as usize]` to not
|
||||||
// have bound checks, and this is the most
|
// have bound checks, and this is the most
|
||||||
|
@ -285,13 +286,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
|
||||||
base::call_assume(&bcx, bcx.icmp(
|
base::call_assume(&bcx, bcx.icmp(
|
||||||
llvm::IntULE,
|
llvm::IntULE,
|
||||||
llval,
|
llval,
|
||||||
C_uint(common::val_ty(llval), max)
|
C_uint(ll_t_in, max)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
signed
|
let signed = match l.abi {
|
||||||
} else {
|
layout::Abi::Scalar(layout::Int(_, signed)) => signed,
|
||||||
operand.ty.is_signed()
|
_ => false
|
||||||
};
|
};
|
||||||
|
|
||||||
let newval = match (r_t_in, r_t_out) {
|
let newval = match (r_t_in, r_t_out) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue