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:
n.Rlist.Set1(r)
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 {
ll[i] = applywritebarrier(n)
}
n = liststmt(append([]*Node{r}, ll...))
n = liststmt(ll)
// x, y = <-c
// orderstmt made sure x is addressable.
......@@ -1848,10 +1849,10 @@ func fncall(l *Node, rt *Type) bool {
// check assign type list to
// a expression list. called in
// 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)
var nn, mm []*Node
var nn, mm Nodes
var ullmanOverflow bool
var i int
for i = 0; i < nl.Len(); i++ {
......@@ -1871,20 +1872,20 @@ func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node {
tmp := temp(r.Type)
tmp = typecheck(tmp, Erv)
a := nod(OAS, l, tmp)
a = convas(a, init)
mm = append(mm, a)
a = convas(a, &mm)
mm.Append(a)
l = tmp
}
a := nod(OAS, l, nodarg(r, fp))
a = convas(a, init)
a := nod(OAS, l, nodarg(r, 0))
a = convas(a, &nn)
ullmancalc(a)
if a.Ullman >= UINF {
Dump("ascompatet ucount", a)
ullmanOverflow = true
}
nn = append(nn, a)
nn.Append(a)
r = saver.Next()
}
......@@ -1895,7 +1896,7 @@ func ascompatet(op Op, nl Nodes, nr *Type, fp int, init *Nodes) []*Node {
if ullmanOverflow {
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.
......
// 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