1
0
mirror of https://github.com/golang/go synced 2024-11-25 21:37:58 -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* static Node*
ascompatee1(int op, Node *l, Node *r, NodeList **init) ascompatee1(int op, Node *l, Node *r, NodeList **init)
{ {
Node *n;
USED(op); USED(op);
return convas(nod(OAS, l, r), init); // 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(n, init);
} }
static NodeList* static NodeList*
@ -1896,13 +1903,14 @@ static int aliased(Node*, NodeList*, NodeList*);
static NodeList* static NodeList*
reorder3(NodeList *all) reorder3(NodeList *all)
{ {
NodeList *list, *early; NodeList *list, *early, *mapinit;
Node *l; Node *l;
// If a needed expression may be affected by an // If a needed expression may be affected by an
// earlier assignment, make an early copy of that // earlier assignment, make an early copy of that
// expression and use the copy instead. // expression and use the copy instead.
early = nil; early = nil;
mapinit = nil;
for(list=all; list; list=list->next) { for(list=all; list; list=list->next) {
l = list->n->left; l = list->n->left;
@ -1926,8 +1934,11 @@ reorder3(NodeList *all)
case ONAME: case ONAME:
break; break;
case OINDEX: case OINDEX:
case OINDEXMAP:
reorder3save(&l->left, all, list, &early); reorder3save(&l->left, all, list, &early);
reorder3save(&l->right, all, list, &early); reorder3save(&l->right, all, list, &early);
if(l->op == OINDEXMAP)
list->n = convas(list->n, &mapinit);
break; break;
case OIND: case OIND:
case ODOTPTR: case ODOTPTR:
@ -1938,6 +1949,7 @@ reorder3(NodeList *all)
reorder3save(&list->n->right, all, list, &early); reorder3save(&list->n->right, all, list, &early);
} }
early = concat(mapinit, early);
return concat(early, all); 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")
}
}