From 61a28d5c881d81cca9156527851911bb5aa5b818 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 16 Sep 2019 15:04:33 +0200 Subject: [PATCH] do the variant idx computations on the host (non-overflowing) --- src/librustc_mir/interpret/operand.rs | 14 ++++++-------- src/librustc_mir/interpret/place.rs | 16 +++++++--------- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 94fbd4ac7d7f3..9e7ae32f1eacf 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -687,24 +687,22 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { (dataful_variant.as_u32() as u128, dataful_variant) }, Ok(raw_discr) => { + // We need to use machine arithmetic to get the relative variant idx. let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; let discr_val = ImmTy::from_uint(raw_discr, discr_layout); - // We need to use machine arithmetic. let niche_start_val = ImmTy::from_uint(niche_start, discr_layout); - let variants_start_val = ImmTy::from_uint(variants_start, discr_layout); let variant_index_relative_val = self.binary_op( mir::BinOp::Sub, discr_val, niche_start_val, )?; - let variant_index_val = self.binary_op( - mir::BinOp::Add, - variant_index_relative_val, - variants_start_val, - )?; - let variant_index = variant_index_val + let variant_index_relative = variant_index_relative_val .to_scalar()? .assert_bits(discr_val.layout.size); + // Then computing the absolute variant idx should not overflow any more. + let variant_index = variants_start + .checked_add(variant_index_relative) + .expect("oveflow computing absolute variant idx"); // Check if this is in the range that indicates an actual discriminant. if variants_start <= variant_index && variant_index <= variants_end { let index = variant_index as usize; diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index 9a3d70144a586..5f4903d61e3b2 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -1060,17 +1060,15 @@ where variant_index.as_usize() < dest.layout.ty.ty_adt_def().unwrap().variants.len(), ); if variant_index != dataful_variant { - let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; - // We need to use machine arithmetic. let variants_start = niche_variants.start().as_u32(); - let variants_start_val = ImmTy::from_uint(variants_start, discr_layout); + let variant_index_relative = variant_index.as_u32() + .checked_sub(variants_start) + .expect("overflow computing relative variant idx"); + // We need to use machine arithmetic when taking into account `niche_start`. + let discr_layout = self.layout_of(discr_layout.value.to_int_ty(*self.tcx))?; let niche_start_val = ImmTy::from_uint(niche_start, discr_layout); - let variant_index_val = ImmTy::from_uint(variant_index.as_u32(), discr_layout); - let variant_index_relative_val = self.binary_op( - mir::BinOp::Sub, - variant_index_val, - variants_start_val, - )?; + let variant_index_relative_val = + ImmTy::from_uint(variant_index_relative, discr_layout); let discr_val = self.binary_op( mir::BinOp::Add, variant_index_relative_val,