]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: emit assignments after calls in the right order
authorKeith Randall <khr@golang.org>
Thu, 27 Oct 2016 16:23:48 +0000 (09:23 -0700)
committerKeith Randall <khr@golang.org>
Thu, 27 Oct 2016 16:52:30 +0000 (16:52 +0000)
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>
src/cmd/compile/internal/gc/walk.go
test/fixedbugs/issue17596.go [new file with mode: 0644]

index 9d21484af24feb8904582c105d995547603a3383..27cbf9152a6ff4f243ccb960d6b970720a29c824 100644 (file)
@@ -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.
diff --git a/test/fixedbugs/issue17596.go b/test/fixedbugs/issue17596.go
new file mode 100644 (file)
index 0000000..7398292
--- /dev/null
@@ -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
+}