cmd/gc: allow map index expressions in for range statements
Fixes #9691.
Change-Id: I22bfc82e05497e91a7b18a668913aed6c723365d
Reviewed-on: https://go-review.googlesource.com/3282
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index 4aa93b2..f3cbd92 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -1454,6 +1454,7 @@
Node* typecheckdef(Node *n);
void copytype(Node *n, Type *t);
void checkreturn(Node*);
+void checkassign(Node*);
void queuemethod(Node *n);
/*
diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c
index 14bb1be..f5f87b2 100644
--- a/src/cmd/gc/range.c
+++ b/src/cmd/gc/range.c
@@ -89,12 +89,14 @@
v1->type = t1;
else if(v1->type != T && assignop(t1, v1->type, &why) == 0)
yyerror("cannot assign type %T to %lN in range%s", t1, v1, why);
+ checkassign(v1);
}
if(v2) {
if(v2->defn == n)
v2->type = t2;
else if(v2->type != T && assignop(t2, v2->type, &why) == 0)
yyerror("cannot assign type %T to %lN in range%s", t2, v2, why);
+ checkassign(v2);
}
out:
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index c71cee9..ef330c6 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -27,7 +27,6 @@
static void typecheckas(Node*);
static void typecheckfunc(Node*);
static void checklvalue(Node*, char*);
-static void checkassign(Node*);
static void checkassignlist(NodeList*);
static void stringtoarraylit(Node**);
static Node* resolve(Node*);
@@ -2811,7 +2810,7 @@
yyerror("cannot %s %N", verb, n);
}
-static void
+void
checkassign(Node *n)
{
if(islvalue(n))
diff --git a/test/fixedbugs/issue9691.go b/test/fixedbugs/issue9691.go
new file mode 100644
index 0000000..39c3dfa
--- /dev/null
+++ b/test/fixedbugs/issue9691.go
@@ -0,0 +1,21 @@
+// run
+
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+func main() {
+ s := "foo"
+ b := []byte(s)
+ m := make(map[string]int)
+ // Test that map index can be used in range
+ // and that slicebytetostringtmp is not used in this context.
+ for m[string(b)] = range s {
+ }
+ b[0] = 'b'
+ if m["foo"] != 2 {
+ panic("bad")
+ }
+}