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: Josh Bleecher Snyder <josharian@gmail.com>
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index 9d21484..27cbf91 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -819,12 +819,13 @@
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 @@
// 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 @@
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 @@
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.
diff --git a/test/fixedbugs/issue17596.go b/test/fixedbugs/issue17596.go
new file mode 100644
index 0000000..7398292
--- /dev/null
+++ b/test/fixedbugs/issue17596.go
@@ -0,0 +1,19 @@
+// 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
+}