Commit a047b6bf authored by Keith Randall's avatar Keith Randall

cmd/compile: emit assignments after calls in the right order

Fixes a bug where assignments that should come after a call
were instead being issued before the call.

Fixes #17596
Fixes #17618

Change-Id: Ic9ae4c34ae38fc4ccd0604b65345b05896a2c295
Reviewed-on: https://go-review.googlesource.com/32226
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
parent dc53ea77
...@@ -819,12 +819,13 @@ opswitch: ...@@ -819,12 +819,13 @@ opswitch:
n.Rlist.Set1(r) n.Rlist.Set1(r)
break break
} }
init.Append(r)
ll := ascompatet(n.Op, n.List, r.Type, 0, init) ll := ascompatet(n.Op, n.List, r.Type)
for i, n := range ll { for i, n := range ll {
ll[i] = applywritebarrier(n) ll[i] = applywritebarrier(n)
} }
n = liststmt(append([]*Node{r}, ll...)) n = liststmt(ll)
// x, y = <-c // x, y = <-c
// orderstmt made sure x is addressable. // orderstmt made sure x is addressable.
...@@ -1848,10 +1849,10 @@ func fncall(l *Node, rt *Type) bool { ...@@ -1848,10 +1849,10 @@ func fncall(l *Node, rt *Type) bool {
// check assign type list to // check assign type list to
// a expression list. called in // a expression list. called in
// expr-list = func() // expr-list = func()
func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node { func ascompatet(op Op, nl Nodes, nr *Type) []*Node {
r, saver := iterFields(nr) r, saver := iterFields(nr)
var nn, mm []*Node var nn, mm Nodes
var ullmanOverflow bool var ullmanOverflow bool
var i int var i int
for i = 0; i < nl.Len(); i++ { for i = 0; i < nl.Len(); i++ {
...@@ -1871,20 +1872,20 @@ func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node { ...@@ -1871,20 +1872,20 @@ func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node {
tmp := temp(r.Type) tmp := temp(r.Type)
tmp = typecheck(tmp, Erv) tmp = typecheck(tmp, Erv)
a := nod(OAS, l, tmp) a := nod(OAS, l, tmp)
a = convas(a, init) a = convas(a, &mm)
mm = append(mm, a) mm.Append(a)
l = tmp l = tmp
} }
a := nod(OAS, l, nodarg(r, fp)) a := nod(OAS, l, nodarg(r, 0))
a = convas(a, init) a = convas(a, &nn)
ullmancalc(a) ullmancalc(a)
if a.Ullman >= UINF { if a.Ullman >= UINF {
Dump("ascompatet ucount", a) Dump("ascompatet ucount", a)
ullmanOverflow = true ullmanOverflow = true
} }
nn = append(nn, a) nn.Append(a)
r = saver.Next() r = saver.Next()
} }
...@@ -1895,7 +1896,7 @@ func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node { ...@@ -1895,7 +1896,7 @@ func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node {
if ullmanOverflow { if ullmanOverflow {
Fatalf("ascompatet: too many function calls evaluating parameters") Fatalf("ascompatet: too many function calls evaluating parameters")
} }
return append(nn, mm...) return append(nn.Slice(), mm.Slice()...)
} }
// package all the arguments that match a ... T parameter into a []T. // package all the arguments that match a ... T parameter into a []T.
......
// compile
// Copyright 2016 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.
package foo
type T interface {
foo()
}
func f() (T, int)
func g(v interface{}) (interface{}, int) {
var x int
v, x = f()
return v, x
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment