Skip to content

Commit 3b66806

Browse files
nikomatsakisbrson
authored andcommitted
prohibit ptr deref unless in unsafe code
1 parent a566985 commit 3b66806

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

src/comp/middle/typeck.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ fn structurally_resolved_type(fcx: @fn_ctxt, sp: span, tp: ty::t) -> ty::t {
193193
}
194194

195195

196-
// Returns the one-level-deep structure of the given type.
196+
// Returns the one-level-deep structure of the given type.f
197197
fn structure_of(fcx: @fn_ctxt, sp: span, typ: ty::t) -> ty::sty {
198198
ret ty::struct(fcx.ccx.tcx, structurally_resolved_type(fcx, sp, typ));
199199
}
@@ -1530,7 +1530,7 @@ fn require_unsafe(sess: session::session, f_purity: ast::purity, sp: span) {
15301530
_ {
15311531
sess.span_fatal(
15321532
sp,
1533-
"Found unsafe expression in safe function decl");
1533+
"unsafe operation requires unsafe function or block");
15341534
}
15351535
}
15361536
}
@@ -1591,6 +1591,23 @@ fn check_expr_with(fcx: @fn_ctxt, expr: @ast::expr, expected: ty::t) -> bool {
15911591
ret check_expr_with_unifier(fcx, expr, demand::simple, expected);
15921592
}
15931593

1594+
fn check_for_unsafe_assignments(fcx: @fn_ctxt, lhs: @ast::expr) {
1595+
alt lhs.node {
1596+
ast::expr_unary(ast::deref., ptr) {
1597+
let ty = expr_ty(fcx.ccx.tcx, ptr);
1598+
let sty = structure_of(fcx, ptr.span, ty);
1599+
alt sty {
1600+
ty::ty_ptr(_) {
1601+
require_unsafe(fcx.ccx.tcx.sess, fcx.purity, lhs.span);
1602+
}
1603+
_ {}
1604+
}
1605+
}
1606+
_ {
1607+
}
1608+
}
1609+
}
1610+
15941611
fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
15951612
expected: ty::t) -> bool {
15961613
//log_err "typechecking expr " + syntax::print::pprust::expr_to_str(expr);
@@ -1702,6 +1719,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
17021719
rhs: @ast::expr, id: ast::node_id) -> bool {
17031720
let t = next_ty_var(fcx);
17041721
let bot = check_expr_with(fcx, lhs, t) | check_expr_with(fcx, rhs, t);
1722+
check_for_unsafe_assignments(fcx, lhs);
17051723
write::ty_only_fixup(fcx, id, ty::mk_nil(fcx.ccx.tcx));
17061724
ret bot;
17071725
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// -*- rust -*-
2+
// error-pattern: unsafe operation requires unsafe function or block
3+
4+
fn f(p: *u8) {
5+
*p = 0u8;
6+
ret;
7+
}
8+
9+
fn main() {
10+
f();
11+
}

0 commit comments

Comments
 (0)