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:
parent
8931306389
commit
5ea52a4d91
@ -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);
|
||||
}
|
||||
|
||||
|
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