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:
parent
8931306389
commit
5ea52a4d91
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
21
test/fixedbugs/issue4620.go
Normal file
21
test/fixedbugs/issue4620.go
Normal 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")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user