Skip to content

Commit bd01eb2

Browse files
committed
---
yaml --- r: 4905 b: refs/heads/master c: c1f2394 h: refs/heads/master i: 4903: 76c72b2 v: v3
1 parent 8e1f043 commit bd01eb2

File tree

3 files changed

+93
-2
lines changed

3 files changed

+93
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: c011f131446d3e2cbbb9266bfefc9fd9637f9bd0
2+
refs/heads/master: c1f239424534af38fd1dfab861fab6813c1c9c97

trunk/src/comp/middle/trans.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4758,6 +4758,11 @@ fn init_local(bcx: @block_ctxt, local: &@ast::local) -> result {
47584758
let llptr = bcx.fcx.lllocals.get(local.node.id);
47594759
// Make a note to drop this slot on the way out.
47604760
add_clean(bcx, llptr, ty);
4761+
4762+
if (must_zero(local)) {
4763+
bcx = zero_alloca(bcx, llptr, ty).bcx;
4764+
}
4765+
47614766
alt local.node.init {
47624767
some(init) {
47634768
alt init.op {
@@ -4775,12 +4780,47 @@ fn init_local(bcx: @block_ctxt, local: &@ast::local) -> result {
47754780
}
47764781
}
47774782
}
4778-
_ { bcx = zero_alloca(bcx, llptr, ty).bcx; }
4783+
_ { }
47794784
}
47804785
bcx =
47814786
trans_alt::bind_irrefutable_pat(bcx, local.node.pat, llptr,
47824787
bcx.fcx.lllocals, false);
47834788
ret rslt(bcx, llptr);
4789+
4790+
fn must_zero(local: &@ast::local) -> bool {
4791+
alt local.node.init {
4792+
some(init) {
4793+
might_not_init(init.expr)
4794+
}
4795+
none. { true }
4796+
}
4797+
}
4798+
4799+
fn might_not_init(expr: &@ast::expr) -> bool {
4800+
type env = @mutable bool;
4801+
let e = @mutable false;
4802+
let visitor = visit::mk_vt(@{
4803+
visit_expr: fn(ex: &@ast::expr, e: &env, v: &vt<env>) {
4804+
// FIXME: Probably also need to account for expressions that
4805+
// fail but since we don't unwind yet, it doesn't seem to be a
4806+
// problem
4807+
let might_not_init = alt ex.node {
4808+
ast::expr_ret(_) { true }
4809+
ast::expr_break. { true }
4810+
ast::expr_cont. { true }
4811+
_ { false }
4812+
};
4813+
if might_not_init {
4814+
*e = true;
4815+
} else {
4816+
visit::visit_expr(ex, e, v);
4817+
}
4818+
}
4819+
with *visit::default_visitor()
4820+
});
4821+
visitor.visit_expr(expr, e, visitor);
4822+
ret *e;
4823+
}
47844824
}
47854825

47864826
fn zero_alloca(cx: &@block_ctxt, llptr: ValueRef, t: ty::t) -> result {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Issue #787
2+
// Don't try to clean up uninitizaed locals
3+
4+
use std;
5+
6+
fn test_break() {
7+
while true {
8+
let x: @int = break;
9+
}
10+
}
11+
12+
fn test_cont() {
13+
let i = 0;
14+
while i < 1 {
15+
i += 1;
16+
let x: @int = cont;
17+
}
18+
}
19+
20+
fn test_ret() {
21+
let x: @int = ret;
22+
}
23+
24+
fn test_fail() {
25+
fn f() {
26+
std::task::unsupervise();
27+
let x: @int = fail;
28+
}
29+
let g = f;
30+
std::task::spawn(g);
31+
}
32+
33+
fn test_fail_indirect() {
34+
fn f() -> ! {
35+
fail;
36+
}
37+
fn g() {
38+
std::task::unsupervise();
39+
let x: @int = f();
40+
}
41+
let h = g;
42+
std::task::spawn(h);
43+
}
44+
45+
fn main() {
46+
test_break();
47+
test_cont();
48+
test_ret();
49+
test_fail();
50+
test_fail_indirect();
51+
}

0 commit comments

Comments
 (0)