cmg/gc: Fix evaluation order of map indexing during multiple assignments

Fixes #4620.

R=rsc
CC=golang-dev
https://golang.org/cl/7241051
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 3bcbb9c..0185a0f 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -1296,9 +1296,16 @@
 static Node*
 ascompatee1(int op, Node *l, Node *r, NodeList **init)
 {
+	Node *n;
 	USED(op);
+	
+	// convas will turn map assigns into function calls,
+	// making it impossible for reorder3 to work.
+	n = nod(OAS, l, r);
+	if(l->op == OINDEXMAP)
+		return n;
 
-	return convas(nod(OAS, l, r), init);
+	return convas(n, init);
 }
 
 static NodeList*
@@ -1896,13 +1903,14 @@
 static NodeList*
 reorder3(NodeList *all)
 {
-	NodeList *list, *early;
+	NodeList *list, *early, *mapinit;
 	Node *l;
 
 	// If a needed expression may be affected by an
 	// earlier assignment, make an early copy of that
 	// expression and use the copy instead.
 	early = nil;
+	mapinit = nil;
 	for(list=all; list; list=list->next) {
 		l = list->n->left;
 
@@ -1926,8 +1934,11 @@
 		case ONAME:
 			break;
 		case OINDEX:
+		case OINDEXMAP:
 			reorder3save(&l->left, all, list, &early);
 			reorder3save(&l->right, all, list, &early);
+			if(l->op == OINDEXMAP)
+				list->n = convas(list->n, &mapinit);
 			break;
 		case OIND:
 		case ODOTPTR:
@@ -1938,6 +1949,7 @@
 		reorder3save(&list->n->right, all, list, &early);
 	}
 
+	early = concat(mapinit, early);
 	return concat(early, all);
 }
 
diff --git a/test/fixedbugs/issue4620.go b/test/fixedbugs/issue4620.go
new file mode 100644
index 0000000..7b4ebf9
--- /dev/null
+++ b/test/fixedbugs/issue4620.go
@@ -0,0 +1,21 @@
+// run
+
+// Copyright 2013 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.
+
+// Issue 4620: map indexes are not evaluated before assignment of other elements
+
+package main
+
+import "fmt"
+
+func main() {
+	m := map[int]int{0:1}
+	i := 0
+	i, m[i] = 1, 2
+	if m[0] != 2 {
+		fmt.Println(m)
+		panic("m[i] != 2")
+	}
+}