mirror of
https://github.com/golang/go
synced 2024-11-23 10:30:03 -07:00
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/12580 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: David Chase <drchase@google.com>
This commit is contained in:
parent
02dd98e9e7
commit
731dcdae6d
@ -301,17 +301,18 @@ func transformclosure(xfunc *Node) {
|
|||||||
// func(a int, byval int, &byref *int) {
|
// func(a int, byval int, &byref *int) {
|
||||||
// println(byval)
|
// println(byval)
|
||||||
// (*&byref)++
|
// (*&byref)++
|
||||||
// }(42, byval, &byref)
|
// }(byval, &byref, 42)
|
||||||
|
|
||||||
// f is ONAME of the actual function.
|
// f is ONAME of the actual function.
|
||||||
f := xfunc.Func.Nname
|
f := xfunc.Func.Nname
|
||||||
|
|
||||||
// Get pointer to input arguments and rewind to the end.
|
// Get pointer to input arguments.
|
||||||
// We are going to append captured variables to input args.
|
// We are going to insert captured variables before input args.
|
||||||
param := &getinargx(f.Type).Type
|
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 v *Node
|
||||||
var addr *Node
|
var addr *Node
|
||||||
var fld *Type
|
var fld *Type
|
||||||
@ -343,12 +344,14 @@ func transformclosure(xfunc *Node) {
|
|||||||
fld.Type = fld.Nname.Type
|
fld.Type = fld.Nname.Type
|
||||||
fld.Sym = fld.Nname.Sym
|
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)
|
xfunc.Func.Dcl = list(xfunc.Func.Dcl, fld.Nname)
|
||||||
|
|
||||||
*param = fld
|
*param = fld
|
||||||
param = &fld.Down
|
param = &fld.Down
|
||||||
}
|
}
|
||||||
|
*param = original_args
|
||||||
|
xfunc.Func.Dcl = concat(xfunc.Func.Dcl, original_dcl)
|
||||||
|
|
||||||
// Recalculate param offsets.
|
// Recalculate param offsets.
|
||||||
if f.Type.Width > 0 {
|
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.
|
// Transform direct call of a closure to call of a normal function.
|
||||||
// transformclosure already did all preparation work.
|
// transformclosure already did all preparation work.
|
||||||
|
|
||||||
// Append captured variables to argument list.
|
// Prepend captured variables to argument list.
|
||||||
n.List = concat(n.List, n.Left.Func.Enter)
|
n.List = concat(n.Left.Func.Enter, n.List)
|
||||||
|
|
||||||
n.Left.Func.Enter = nil
|
n.Left.Func.Enter = nil
|
||||||
|
|
||||||
|
20
test/fixedbugs/issue11750.go
Normal file
20
test/fixedbugs/issue11750.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// 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")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user