Commit 731dcdae authored by David Chase's avatar David Chase

cmd/compile: prepend captured args to called-closure params

Old code appended, did not play well with a closure
with a ... param.

Fixes #11075.

Change-Id: Ib7c8590c5c4e576e798837e7499e00f3494efb4a
Reviewed-on: https://go-review.googlesource.com/12580Reviewed-by: default avatarRuss Cox <rsc@golang.org>
Run-TryBot: David Chase <drchase@google.com>
parent 02dd98e9
......@@ -301,17 +301,18 @@ func transformclosure(xfunc *Node) {
// func(a int, byval int, &byref *int) {
// println(byval)
// (*&byref)++
// }(42, byval, &byref)
// }(byval, &byref, 42)
// f is ONAME of the actual function.
f := xfunc.Func.Nname
// Get pointer to input arguments and rewind to the end.
// We are going to append captured variables to input args.
// Get pointer to input arguments.
// We are going to insert captured variables before input args.
param := &getinargx(f.Type).Type
original_args := *param // old input args
original_dcl := xfunc.Func.Dcl
xfunc.Func.Dcl = nil
for ; *param != nil; param = &(*param).Down {
}
var v *Node
var addr *Node
var fld *Type
......@@ -343,12 +344,14 @@ func transformclosure(xfunc *Node) {
fld.Type = fld.Nname.Type
fld.Sym = fld.Nname.Sym
// Declare the new param and append it to input arguments.
// Declare the new param and add it the first part of the input arguments.
xfunc.Func.Dcl = list(xfunc.Func.Dcl, fld.Nname)
*param = fld
param = &fld.Down
}
*param = original_args
xfunc.Func.Dcl = concat(xfunc.Func.Dcl, original_dcl)
// Recalculate param offsets.
if f.Type.Width > 0 {
......
......@@ -609,8 +609,8 @@ func walkexpr(np **Node, init **NodeList) {
// Transform direct call of a closure to call of a normal function.
// transformclosure already did all preparation work.
// Append captured variables to argument list.
n.List = concat(n.List, n.Left.Func.Enter)
// Prepend captured variables to argument list.
n.List = concat(n.Left.Func.Enter, n.List)
n.Left.Func.Enter = nil
......
// compile
// Copyright 2015 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.
// Issue 11750: mkdotargslice: typecheck failed
package main
func main() {
fn := func(names string) {
}
func(names ...string) {
for _, name := range names {
fn(name)
}
}("one", "two")
}
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