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>
diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go
index 65f77d9..a0dfa0b 100644
--- a/src/cmd/compile/internal/gc/closure.go
+++ b/src/cmd/compile/internal/gc/closure.go
@@ -301,17 +301,18 @@
 		//	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 @@
 			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 {
diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go
index d89d25e..91c0a47 100644
--- a/src/cmd/compile/internal/gc/walk.go
+++ b/src/cmd/compile/internal/gc/walk.go
@@ -609,8 +609,8 @@
 			// 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