aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/range.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/range.go')
-rw-r--r--src/cmd/compile/internal/gc/range.go18
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])