diff options
Diffstat (limited to 'src/cmd/compile/internal/gc/range.go')
| -rw-r--r-- | src/cmd/compile/internal/gc/range.go | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/gc/range.go b/src/cmd/compile/internal/gc/range.go index 6adf8e0d6d..9d3f79cdce 100644 --- a/src/cmd/compile/internal/gc/range.go +++ b/src/cmd/compile/internal/gc/range.go @@ -49,7 +49,7 @@ func typecheckrange(n *Node) { Yyerror("cannot range over %v", Nconv(n.Right, FmtLong)) goto out - case TARRAY: + case TARRAY, TSLICE: t1 = Types[TINT] t2 = t.Elem() @@ -154,7 +154,7 @@ func walkrange(n *Node) { v2 = n.List.Second() } - // n->list has no meaning anymore, clear it + // n.List has no meaning anymore, clear it // to avoid erroneous processing by racewalk. n.List.Set(nil) @@ -164,7 +164,7 @@ func walkrange(n *Node) { default: Fatalf("walkrange") - case TARRAY: + case TARRAY, TSLICE: if memclrrange(n, v1, v2, a) { lineno = lno return @@ -217,9 +217,9 @@ func walkrange(n *Node) { n.Right.Ninit.Set1(a) } - // orderstmt allocated the iterator for us. - // we only use a once, so no copy needed. case TMAP: + // orderstmt allocated the iterator for us. + // we only use a once, so no copy needed. ha := a th := hiter(t) @@ -254,8 +254,8 @@ func walkrange(n *Node) { body = []*Node{a} } - // orderstmt arranged for a copy of the channel variable. case TCHAN: + // orderstmt arranged for a copy of the channel variable. ha := a n.Left = nil @@ -278,9 +278,13 @@ func walkrange(n *Node) { } else { body = []*Node{Nod(OAS, v1, hv1)} } + // Zero hv1. This prevents hv1 from being the sole, inaccessible + // reference to an otherwise GC-able value during the next channel receive. + // See issue 15281. + body = append(body, Nod(OAS, hv1, nil)) - // orderstmt arranged for a copy of the string variable. case TSTRING: + // orderstmt arranged for a copy of the string variable. ha := a ohv1 := temp(Types[TINT]) |
