Skip to content

Commit d889ded

Browse files
authored
Merge pull request rust-lang#101 from oli-obk/small_fixes
various small fixes
2 parents f375222 + e7ef118 commit d889ded

File tree

4 files changed

+106
-6
lines changed

4 files changed

+106
-6
lines changed

src/eval_context.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -517,10 +517,6 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
517517
let operand = &operands[0];
518518
let value = self.eval_operand(operand)?;
519519
let value_ty = self.operand_ty(operand);
520-
521-
// FIXME(solson)
522-
let dest = self.force_allocation(dest)?;
523-
524520
self.write_value(value, dest, value_ty)?;
525521
}
526522

@@ -692,7 +688,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
692688
Ok((offset, ty))
693689
}
694690

695-
fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx, Ty<'tcx>> {
691+
pub fn get_field_ty(&self, ty: Ty<'tcx>, field_index: usize) -> EvalResult<'tcx, Ty<'tcx>> {
696692
match ty.sty {
697693
ty::TyAdt(adt_def, substs) => {
698694
Ok(adt_def.struct_variant().fields[field_index].ty(self.tcx, substs))
@@ -1015,7 +1011,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
10151011
Ok(())
10161012
}
10171013

1018-
pub(super) fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimValKind> {
1014+
pub fn ty_to_primval_kind(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, PrimValKind> {
10191015
use syntax::ast::FloatTy;
10201016

10211017
let kind = match ty.sty {

src/terminator/intrinsic.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
6666
}
6767

6868
"atomic_store" |
69+
"atomic_store_relaxed" |
70+
"atomic_store_rel" |
6971
"volatile_store" => {
7072
let ty = substs.type_at(0);
7173
let dest = arg_vals[0].read_ptr(&self.memory)?;
@@ -90,6 +92,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
9092
self.write_primval(Lvalue::from_ptr(ptr), change, ty)?;
9193
}
9294

95+
"atomic_cxchg_relaxed" |
9396
"atomic_cxchg" => {
9497
let ty = substs.type_at(0);
9598
let ptr = arg_vals[0].read_ptr(&self.memory)?;
@@ -108,6 +111,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
108111
self.write_primval(Lvalue::from_ptr(ptr), change, ty)?;
109112
}
110113

114+
"atomic_xadd" |
111115
"atomic_xadd_relaxed" => {
112116
let ty = substs.type_at(0);
113117
let ptr = arg_vals[0].read_ptr(&self.memory)?;

src/terminator/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,18 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
405405
self.write_primval(dest, PrimVal::Bytes(result as u128), dest_ty)?;
406406
}
407407

408+
"memrchr" => {
409+
let ptr = args[0].read_ptr(&self.memory)?;
410+
let val = self.value_to_primval(args[1], usize)?.to_u64()? as u8;
411+
let num = self.value_to_primval(args[2], usize)?.to_u64()?;
412+
if let Some(idx) = self.memory.read_bytes(ptr, num)?.iter().rev().position(|&c| c == val) {
413+
let new_ptr = ptr.offset(num - idx as u64 - 1);
414+
self.write_value(Value::ByVal(PrimVal::Ptr(new_ptr)), dest, dest_ty)?;
415+
} else {
416+
self.write_value(Value::ByVal(PrimVal::Bytes(0)), dest, dest_ty)?;
417+
}
418+
}
419+
408420
"memchr" => {
409421
let ptr = args[0].read_ptr(&self.memory)?;
410422
let val = self.value_to_primval(args[1], usize)?.to_u64()? as u8;

tests/run-pass/union.rs

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#![feature(untagged_unions)]
2+
#![allow(dead_code, unused_variables)]
3+
4+
fn main() {
5+
a();
6+
b();
7+
c();
8+
d();
9+
}
10+
11+
fn a() {
12+
union U {
13+
f1: u32,
14+
f2: f32,
15+
}
16+
let mut u = U { f1: 1 };
17+
unsafe {
18+
let b1 = &mut u.f1;
19+
*b1 = 5;
20+
}
21+
assert_eq!(unsafe { u.f1 }, 5);
22+
}
23+
24+
fn b() {
25+
struct S {
26+
x: u32,
27+
y: u32,
28+
}
29+
30+
union U {
31+
s: S,
32+
both: u64,
33+
}
34+
let mut u = U { s: S { x: 1, y: 2 } };
35+
unsafe {
36+
let bx = &mut u.s.x;
37+
let by = &mut u.s.y;
38+
*bx = 5;
39+
*by = 10;
40+
}
41+
assert_eq!(unsafe { u.s.x }, 5);
42+
assert_eq!(unsafe { u.s.y }, 10);
43+
}
44+
45+
fn c() {
46+
#[repr(u32)]
47+
enum Tag { I, F }
48+
49+
#[repr(C)]
50+
union U {
51+
i: i32,
52+
f: f32,
53+
}
54+
55+
#[repr(C)]
56+
struct Value {
57+
tag: Tag,
58+
u: U,
59+
}
60+
61+
fn is_zero(v: Value) -> bool {
62+
unsafe {
63+
match v {
64+
Value { tag: Tag::I, u: U { i: 0 } } => true,
65+
Value { tag: Tag::F, u: U { f: 0.0 } } => true,
66+
_ => false,
67+
}
68+
}
69+
}
70+
assert!(is_zero(Value { tag: Tag::I, u: U { i: 0 }}));
71+
assert!(is_zero(Value { tag: Tag::F, u: U { f: 0.0 }}));
72+
assert!(!is_zero(Value { tag: Tag::I, u: U { i: 1 }}));
73+
assert!(!is_zero(Value { tag: Tag::F, u: U { f: 42.0 }}));
74+
}
75+
76+
fn d() {
77+
union MyUnion {
78+
f1: u32,
79+
f2: f32,
80+
}
81+
let u = MyUnion { f1: 10 };
82+
unsafe {
83+
match u {
84+
MyUnion { f1: 10 } => { }
85+
MyUnion { f2 } => { panic!("foo"); }
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)