mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-09 16:37:36 +00:00
commit
d889deda5a
@ -517,10 +517,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
let operand = &operands[0];
|
||||
let value = self.eval_operand(operand)?;
|
||||
let value_ty = self.operand_ty(operand);
|
||||
|
||||
// FIXME(solson)
|
||||
let dest = self.force_allocation(dest)?;
|
||||
|
||||
self.write_value(value, dest, value_ty)?;
|
||||
}
|
||||
|
||||
@ -692,7 +688,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
Ok((offset, ty))
|
||||
}
|
||||
|
||||
fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx, Ty<'tcx>> {
|
||||
pub fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx, Ty<'tcx>> {
|
||||
match ty.sty {
|
||||
ty::TyAdt(adt_def, substs) => {
|
||||
Ok(adt_def.struct_variant().fields[field_index].ty(self.tcx, substs))
|
||||
@ -1015,7 +1011,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimValKind> {
|
||||
pub fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimValKind> {
|
||||
use syntax::ast::FloatTy;
|
||||
|
||||
let kind = match ty.sty {
|
||||
|
@ -66,6 +66,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
}
|
||||
|
||||
"atomic_store" |
|
||||
"atomic_store_relaxed" |
|
||||
"atomic_store_rel" |
|
||||
"volatile_store" => {
|
||||
let ty = substs.type_at(0);
|
||||
let dest = arg_vals[0].read_ptr(&self.memory)?;
|
||||
@ -90,6 +92,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
self.write_primval(Lvalue::from_ptr(ptr), change, ty)?;
|
||||
}
|
||||
|
||||
"atomic_cxchg_relaxed" |
|
||||
"atomic_cxchg" => {
|
||||
let ty = substs.type_at(0);
|
||||
let ptr = arg_vals[0].read_ptr(&self.memory)?;
|
||||
@ -108,6 +111,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
self.write_primval(Lvalue::from_ptr(ptr), change, ty)?;
|
||||
}
|
||||
|
||||
"atomic_xadd" |
|
||||
"atomic_xadd_relaxed" => {
|
||||
let ty = substs.type_at(0);
|
||||
let ptr = arg_vals[0].read_ptr(&self.memory)?;
|
||||
|
@ -405,6 +405,18 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
||||
self.write_primval(dest, PrimVal::Bytes(result as u128), dest_ty)?;
|
||||
}
|
||||
|
||||
"memrchr" => {
|
||||
let ptr = args[0].read_ptr(&self.memory)?;
|
||||
let val = self.value_to_primval(args[1], usize)?.to_u64()? as u8;
|
||||
let num = self.value_to_primval(args[2], usize)?.to_u64()?;
|
||||
if let Some(idx) = self.memory.read_bytes(ptr, num)?.iter().rev().position(|&c| c == val) {
|
||||
let new_ptr = ptr.offset(num - idx as u64 - 1);
|
||||
self.write_value(Value::ByVal(PrimVal::Ptr(new_ptr)), dest, dest_ty)?;
|
||||
} else {
|
||||
self.write_value(Value::ByVal(PrimVal::Bytes(0)), dest, dest_ty)?;
|
||||
}
|
||||
}
|
||||
|
||||
"memchr" => {
|
||||
let ptr = args[0].read_ptr(&self.memory)?;
|
||||
let val = self.value_to_primval(args[1], usize)?.to_u64()? as u8;
|
||||
|
88
tests/run-pass/union.rs
Normal file
88
tests/run-pass/union.rs
Normal file
@ -0,0 +1,88 @@
|
||||
#![feature(untagged_unions)]
|
||||
#![allow(dead_code, unused_variables)]
|
||||
|
||||
fn main() {
|
||||
a();
|
||||
b();
|
||||
c();
|
||||
d();
|
||||
}
|
||||
|
||||
fn a() {
|
||||
union U {
|
||||
f1: u32,
|
||||
f2: f32,
|
||||
}
|
||||
let mut u = U { f1: 1 };
|
||||
unsafe {
|
||||
let b1 = &mut u.f1;
|
||||
*b1 = 5;
|
||||
}
|
||||
assert_eq!(unsafe { u.f1 }, 5);
|
||||
}
|
||||
|
||||
fn b() {
|
||||
struct S {
|
||||
x: u32,
|
||||
y: u32,
|
||||
}
|
||||
|
||||
union U {
|
||||
s: S,
|
||||
both: u64,
|
||||
}
|
||||
let mut u = U { s: S { x: 1, y: 2 } };
|
||||
unsafe {
|
||||
let bx = &mut u.s.x;
|
||||
let by = &mut u.s.y;
|
||||
*bx = 5;
|
||||
*by = 10;
|
||||
}
|
||||
assert_eq!(unsafe { u.s.x }, 5);
|
||||
assert_eq!(unsafe { u.s.y }, 10);
|
||||
}
|
||||
|
||||
fn c() {
|
||||
#[repr(u32)]
|
||||
enum Tag { I, F }
|
||||
|
||||
#[repr(C)]
|
||||
union U {
|
||||
i: i32,
|
||||
f: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct Value {
|
||||
tag: Tag,
|
||||
u: U,
|
||||
}
|
||||
|
||||
fn is_zero(v: Value) -> bool {
|
||||
unsafe {
|
||||
match v {
|
||||
Value { tag: Tag::I, u: U { i: 0 } } => true,
|
||||
Value { tag: Tag::F, u: U { f: 0.0 } } => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
assert!(is_zero(Value { tag: Tag::I, u: U { i: 0 }}));
|
||||
assert!(is_zero(Value { tag: Tag::F, u: U { f: 0.0 }}));
|
||||
assert!(!is_zero(Value { tag: Tag::I, u: U { i: 1 }}));
|
||||
assert!(!is_zero(Value { tag: Tag::F, u: U { f: 42.0 }}));
|
||||
}
|
||||
|
||||
fn d() {
|
||||
union MyUnion {
|
||||
f1: u32,
|
||||
f2: f32,
|
||||
}
|
||||
let u = MyUnion { f1: 10 };
|
||||
unsafe {
|
||||
match u {
|
||||
MyUnion { f1: 10 } => { }
|
||||
MyUnion { f2 } => { panic!("foo"); }
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user