Skip to content

Commit

Permalink
miri-engine value visitor update to VariantIdx
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Nov 12, 2018
1 parent 4a9ed3f commit b174b0b
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 10 deletions.
30 changes: 26 additions & 4 deletions src/librustc_mir/interpret/validity.rs
Expand Up @@ -13,7 +13,7 @@ use std::hash::Hash;
use std::ops::RangeInclusive;

use syntax_pos::symbol::Symbol;
use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf};
use rustc::ty::layout::{self, Size, Align, TyLayout, LayoutOf, VariantIdx};
use rustc::ty;
use rustc_data_structures::fx::FxHashSet;
use rustc::mir::interpret::{
Expand Down Expand Up @@ -74,6 +74,7 @@ macro_rules! try_validation {
#[derive(Copy, Clone, Debug)]
pub enum PathElem {
Field(Symbol),
Variant(Symbol),
ClosureVar(Symbol),
ArrayElem(usize),
TupleElem(usize),
Expand Down Expand Up @@ -107,6 +108,7 @@ fn path_format(path: &Vec<PathElem>) -> String {
for elem in path.iter() {
match elem {
Field(name) => write!(out, ".{}", name),
Variant(name) => write!(out, ".<downcast-variant({})>", name),
ClosureVar(name) => write!(out, ".<closure-var({})>", name),
TupleElem(idx) => write!(out, ".{}", idx),
ArrayElem(idx) => write!(out, "[{}]", idx),
Expand Down Expand Up @@ -192,9 +194,11 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, '
layout::Variants::Single { index } =>
// Inside a variant
PathElem::Field(def.variants[index].fields[field].ident.name),
_ =>
// To a variant
PathElem::Field(def.variants[field].name)
_ => {
// Enums have no fields other than their tag
assert_eq!(field, 0);
PathElem::Tag
}
}
}

Expand Down Expand Up @@ -241,6 +245,24 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
Ok(())
}

#[inline]
fn visit_variant(
&mut self,
old_op: OpTy<'tcx, M::PointerTag>,
variant_id: VariantIdx,
new_op: OpTy<'tcx, M::PointerTag>
) -> EvalResult<'tcx> {
// Remember the old state
let path_len = self.path.len();
// Perform operation
let name = old_op.layout.ty.ty_adt_def().unwrap().variants[variant_id].name;
self.path.push(PathElem::Variant(name));
self.visit_value(new_op)?;
// Undo changes
self.path.truncate(path_len);
Ok(())
}

#[inline]
fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
{
Expand Down
20 changes: 15 additions & 5 deletions src/librustc_mir/interpret/visitor.rs
@@ -1,7 +1,7 @@
//! Visitor for a run-time value with a given layout: Traverse enums, structs and other compound
//! types until we arrive at the leaves, with custom handling for primitive types.

use rustc::ty::layout::{self, TyLayout};
use rustc::ty::layout::{self, TyLayout, VariantIdx};
use rustc::ty;
use rustc::mir::interpret::{
EvalResult,
Expand Down Expand Up @@ -32,7 +32,7 @@ pub trait Value<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>: Copy
fn project_downcast(
self,
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
variant: usize,
variant: VariantIdx,
) -> EvalResult<'tcx, Self>;

/// Project to the n-th field.
Expand Down Expand Up @@ -70,7 +70,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
fn project_downcast(
self,
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
variant: usize,
variant: VariantIdx,
) -> EvalResult<'tcx, Self> {
ecx.operand_downcast(self, variant)
}
Expand Down Expand Up @@ -109,7 +109,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> Value<'a, 'mir, 'tcx, M>
fn project_downcast(
self,
ecx: &EvalContext<'a, 'mir, 'tcx, M>,
variant: usize,
variant: VariantIdx,
) -> EvalResult<'tcx, Self> {
ecx.mplace_downcast(self, variant)
}
Expand Down Expand Up @@ -171,6 +171,16 @@ macro_rules! make_value_visitor {
self.visit_value(new_val)
}

#[inline(always)]
fn visit_variant(
&mut self,
_old_val: Self::V,
_variant: VariantIdx,
new_val: Self::V,
) -> EvalResult<'tcx> {
self.visit_value(new_val)
}

/// Called whenever we reach a value with uninhabited layout.
/// Recursing to fields will *always* continue after this! This is not meant to control
/// whether and how we descend recursively/ into the scalar's fields if there are any,
Expand Down Expand Up @@ -221,7 +231,7 @@ macro_rules! make_value_visitor {
let inner = v.project_downcast(self.ecx(), idx)?;
trace!("walk_value: variant layout: {:#?}", inner.layout());
// recurse with the inner type
return self.visit_field(v, idx, inner);
return self.visit_variant(v, idx, inner);
}
layout::Variants::Single { .. } => {}
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/consts/const-eval/ub-enum.stderr
Expand Up @@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-enum.rs:61:1
|
LL | const BAD_ENUM_CHAR: Option<(char, char)> = Some(('x', unsafe { TransmuteChar { a: !0 }.b }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .Some.0.1, but expected something less or equal to 1114111
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 4294967295 at .<downcast-variant(Some)>.0.1, but expected something less or equal to 1114111
|
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior

Expand Down

0 comments on commit b174b0b

Please sign in to comment.