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")
+	}
+}