]> Cypherpunks repositories - gostls13.git/commitdiff
cmg/gc: Fix evaluation order of map indexing during multiple assignments
authorDaniel Morsing <daniel.morsing@gmail.com>
Sat, 2 Feb 2013 11:39:04 +0000 (12:39 +0100)
committerDaniel Morsing <daniel.morsing@gmail.com>
Sat, 2 Feb 2013 11:39:04 +0000 (12:39 +0100)
Fixes #4620.

R=rsc
CC=golang-dev
https://golang.org/cl/7241051

src/cmd/gc/walk.c
test/fixedbugs/issue4620.go [new file with mode: 0644]

index 3bcbb9cd74cac4e0cd7aa906a4bbcb0999b48184..0185a0f9f454492c3519498400c7b3f56569178b 100644 (file)
@@ -1296,9 +1296,16 @@ ret:
 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 int aliased(Node*, NodeList*, NodeList*);
 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 @@ reorder3(NodeList *all)
                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 @@ reorder3(NodeList *all)
                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 (file)
index 0000000..7b4ebf9
--- /dev/null
@@ -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")
+       }
+}