rustc: Implement pointer dereference; add a test case

This commit is contained in:
Patrick Walton 2011-07-11 15:14:07 -07:00
parent 4618e802db
commit 79ce5a4614
5 changed files with 30 additions and 4 deletions

View File

@ -573,6 +573,7 @@ fn expr_root(&ctx cx, @ast::expr ex, bool autoderef) ->
case (ty::ty_box(?mt)) { mut = mt.mut != ast::imm; }
case (ty::ty_res(_, _, _)) {}
case (ty::ty_tag(_, _)) {}
case (ty::ty_ptr(?mt)) { mut = mt.mut != ast::imm; }
}
vec::push(ds, rec(mut=mut, kind=unbox, outer_t=base_t));
ex = base;

View File

@ -5263,11 +5263,11 @@ fn trans_lval_gen(&@block_ctxt cx, &@ast::expr e) -> lval_result {
auto t = ty::expr_ty(ccx.tcx, base);
auto val = alt (ty::struct(ccx.tcx, t)) {
case (ty::ty_box(_)) {
sub.bcx.build.GEP
sub.bcx.build.InBoundsGEP
(sub.val, ~[C_int(0), C_int(abi::box_rc_field_body)])
}
case (ty::ty_res(_, _, _)) {
sub.bcx.build.GEP(sub.val, ~[C_int(0), C_int(1)])
sub.bcx.build.InBoundsGEP(sub.val, ~[C_int(0), C_int(1)])
}
case (ty::ty_tag(_, _)) {
auto ety = ty::expr_ty(ccx.tcx, e);
@ -5279,6 +5279,7 @@ fn trans_lval_gen(&@block_ctxt cx, &@ast::expr e) -> lval_result {
};
sub.bcx.build.PointerCast(sub.val, ellty)
}
case (ty::ty_ptr(_)) { sub.val }
};
ret lval_mem(sub.bcx, val);
}

View File

@ -1712,6 +1712,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
oper_t = ty::substitute_type_params
(fcx.ccx.tcx, tps, variants.(0).args.(0));
}
case (ty::ty_ptr(?inner)) { oper_t = inner.ty; }
case (_) {
fcx.ccx.tcx.sess.span_fatal
(expr.span, "dereferencing non-" +

View File

@ -1,10 +1,10 @@
// Unsafe pointer utility functions.
native "rust-intrinsic" mod rusti {
fn addr_of[T](&T val) -> *T;
fn addr_of[T](&mutable T val) -> *mutable T;
fn ptr_offset[T](*T ptr, uint count) -> *T;
}
fn addr_of[T](&T val) -> *T { ret rusti::addr_of(val); }
fn addr_of[T](&mutable T val) -> *mutable T { ret rusti::addr_of(val); }
fn offset[T](*T ptr, uint count) -> *T { ret rusti::ptr_offset(ptr, count); }

View File

@ -0,0 +1,23 @@
// xfail-stage0
use std;
import std::ptr;
import std::unsafe;
type pair = rec(mutable int fst, mutable int snd);
fn main() {
auto p = rec(mutable fst=10, mutable snd=20);
let *mutable pair pptr = ptr::addr_of(p);
let *mutable int iptr = unsafe::reinterpret_cast(pptr);
assert (*iptr == 10);
*iptr = 30;
assert (*iptr == 30);
assert (p.fst == 30);
*pptr = rec(mutable fst=50, mutable snd=60);
assert (*iptr == 50);
assert (p.fst == 50);
assert (p.snd == 60);
}