From 35502fd47daf3a95d01e3a538e429c7ceb9de03b Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Fri, 24 Feb 2017 10:39:55 +0100 Subject: [PATCH] rustup --- src/eval_context.rs | 19 ++++++++++++++++--- src/lib.rs | 1 - src/step.rs | 2 ++ src/terminator/drop.rs | 2 +- src/terminator/mod.rs | 39 ++++++++------------------------------- 5 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/eval_context.rs b/src/eval_context.rs index 13fad7b4644..54aae64c5ca 100644 --- a/src/eval_context.rs +++ b/src/eval_context.rs @@ -456,7 +456,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { General { discr, ref variants, .. } => { if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind { - let discr_val = adt_def.variants[variant].disr_val.to_u128_unchecked(); + let discr_val = adt_def.variants[variant].disr_val; let discr_size = discr.size().bytes(); if variants[variant].packed { let ptr = self.force_allocation(dest)?.to_ptr_and_extra().0; @@ -529,7 +529,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { CEnum { .. } => { assert_eq!(operands.len(), 0); if let mir::AggregateKind::Adt(adt_def, variant, _, _) = *kind { - let n = adt_def.variants[variant].disr_val.to_u128_unchecked(); + let n = adt_def.variants[variant].disr_val; self.write_primval(dest, PrimVal::Bytes(n), dest_ty)?; } else { bug!("tried to assign {:?} to Layout::CEnum", kind); @@ -661,7 +661,20 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { } } - InlineAsm { .. } => return Err(EvalError::InlineAsm), + Discriminant(ref lvalue) => { + let lval = self.eval_lvalue(lvalue)?; + let ty = self.lvalue_ty(lvalue); + let ptr = self.force_allocation(lval)?.to_ptr(); + let discr_val = self.read_discriminant_value(ptr, ty)?; + if let ty::TyAdt(adt_def, _) = ty.sty { + if adt_def.variants.iter().all(|v| discr_val != v.disr_val) { + return Err(EvalError::InvalidDiscriminant); + } + } else { + bug!("rustc only generates Rvalue::Discriminant for enums"); + } + self.write_primval(dest, PrimVal::Bytes(discr_val), dest_ty)?; + }, } if log_enabled!(::log::LogLevel::Trace) { diff --git a/src/lib.rs b/src/lib.rs index 290b478eb64..d1d8e8cf229 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,6 @@ #![feature( btree_range, collections, - field_init_shorthand, i128_type, pub_restricted, rustc_private, diff --git a/src/step.rs b/src/step.rs index 5c957f0cdc0..c08ac9693a4 100644 --- a/src/step.rs +++ b/src/step.rs @@ -119,6 +119,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { // Defined to do nothing. These are added by optimization passes, to avoid changing the // size of MIR constantly. Nop => {} + + InlineAsm { .. } => return Err(EvalError::InlineAsm), } self.frame_mut().stmt += 1; diff --git a/src/terminator/drop.rs b/src/terminator/drop.rs index 71f3d467366..dd199a4266c 100644 --- a/src/terminator/drop.rs +++ b/src/terminator/drop.rs @@ -121,7 +121,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { Layout::General { .. } => { let discr_val = self.read_discriminant_value(adt_ptr, ty)? as u128; let ptr = self.force_allocation(lval)?.to_ptr(); - match adt_def.variants.iter().position(|v| discr_val == v.disr_val.to_u128_unchecked()) { + match adt_def.variants.iter().position(|v| discr_val == v.disr_val) { Some(i) => { lval = Lvalue::Ptr { ptr, diff --git a/src/terminator/mod.rs b/src/terminator/mod.rs index 4fb39681613..183a3f54fb6 100644 --- a/src/terminator/mod.rs +++ b/src/terminator/mod.rs @@ -35,22 +35,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { Goto { target } => self.goto_block(target), - If { ref cond, targets: (then_target, else_target) } => { - let cond_val = self.eval_operand_to_primval(cond)?.to_bool()?; - self.goto_block(if cond_val { then_target } else { else_target }); - } - SwitchInt { ref discr, ref values, ref targets, .. } => { - let discr_val = self.eval_and_read_lvalue(discr)?; - let discr_ty = self.lvalue_ty(discr); + let discr_val = self.eval_operand(discr)?; + let discr_ty = self.operand_ty(discr); let discr_prim = self.value_to_primval(discr_val, discr_ty)?; // Branch to the `otherwise` case by default, if no match is found. let mut target_block = targets[targets.len() - 1]; - for (index, const_val) in values.iter().enumerate() { - let val = self.const_to_value(const_val)?; - let prim = self.value_to_primval(val, discr_ty)?; + for (index, const_int) in values.iter().enumerate() { + let prim = PrimVal::Bytes(const_int.to_u128_unchecked()); if discr_prim.to_bytes()? == prim.to_bytes()? { target_block = targets[index]; break; @@ -60,23 +54,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { self.goto_block(target_block); } - Switch { ref discr, ref targets, adt_def } => { - // FIXME(solson) - let lvalue = self.eval_lvalue(discr)?; - let lvalue = self.force_allocation(lvalue)?; - - let adt_ptr = lvalue.to_ptr(); - let adt_ty = self.lvalue_ty(discr); - let discr_val = self.read_discriminant_value(adt_ptr, adt_ty)?; - let matching = adt_def.variants.iter() - .position(|v| discr_val == v.disr_val.to_u128_unchecked()); - - match matching { - Some(i) => self.goto_block(targets[i]), - None => return Err(EvalError::InvalidDiscriminant), - } - } - Call { ref func, ref args, ref destination, .. } => { let destination = match *destination { Some((ref lv, target)) => Some((self.eval_lvalue(lv)?, target)), @@ -216,12 +193,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { trace!("layout({:?}) = {:#?}", dest_ty, dest_layout); match *dest_layout { Layout::Univariant { .. } => { - let disr_val = v.disr_val.to_u128_unchecked(); + let disr_val = v.disr_val; assert_eq!(disr_val, 0); self.assign_fields(lvalue, dest_ty, args)?; }, Layout::General { discr, ref variants, .. } => { - let disr_val = v.disr_val.to_u128_unchecked(); + let disr_val = v.disr_val; let discr_size = discr.size().bytes(); self.assign_discr_and_fields( lvalue, @@ -234,7 +211,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { )?; }, Layout::StructWrappedNullablePointer { nndiscr, ref discrfield, .. } => { - let disr_val = v.disr_val.to_u128_unchecked(); + let disr_val = v.disr_val; if nndiscr as u128 == disr_val { self.assign_fields(lvalue, dest_ty, args)?; } else { @@ -325,7 +302,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { } } - fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u128> { + pub fn read_discriminant_value(&self, adt_ptr: Pointer, adt_ty: Ty<'tcx>) -> EvalResult<'tcx, u128> { use rustc::ty::layout::Layout::*; let adt_layout = self.type_layout(adt_ty)?; trace!("read_discriminant_value {:#?}", adt_layout);