1
0
mirror of https://github.com/golang/go synced 2024-11-25 16:17:56 -07:00

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

Fixes #4620.

R=rsc
CC=golang-dev
https://golang.org/cl/7241051
This commit is contained in:
Daniel Morsing 2013-02-02 12:39:04 +01:00
parent 8931306389
commit 5ea52a4d91
2 changed files with 35 additions and 2 deletions

View 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);
}

View File

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