From a047b6bf7d90cc7185f18af3c179dfc7e66b66e9 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 27 Oct 2016 09:23:48 -0700 Subject: [PATCH] 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 TryBot-Result: Gobot Gobot Reviewed-by: Josh Bleecher Snyder --- src/cmd/compile/internal/gc/walk.go | 21 +++++++++++---------- test/fixedbugs/issue17596.go | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) create mode 100644 test/fixedbugs/issue17596.go diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 9d21484af2..27cbf9152a 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -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 index 0000000000..7398292d43 --- /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 +} -- 2.48.1