From: Rémy Oudompheng Date: Mon, 8 Apr 2013 06:59:33 +0000 (+0200) Subject: cmd/gc: properly set variadic flag on method values. X-Git-Tag: go1.1rc2~140 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=20e05303febf53d959926a05c6f019db352bb963;p=gostls13.git cmd/gc: properly set variadic flag on method values. Fixes #5231. R=golang-dev, daniel.morsing, adg CC=golang-dev https://golang.org/cl/8275044 --- diff --git a/src/cmd/gc/closure.c b/src/cmd/gc/closure.c index c1a9eb14cc..962b088452 100644 --- a/src/cmd/gc/closure.c +++ b/src/cmd/gc/closure.c @@ -280,12 +280,12 @@ typecheckpartialcall(Node *fn, Node *sym) static Node* makepartialcall(Node *fn, Type *t0, Node *meth) { - Node *ptr, *n, *call, *xtype, *xfunc, *cv; + Node *ptr, *n, *fld, *call, *xtype, *xfunc, *cv; Type *rcvrtype, *basetype, *t; NodeList *body, *l, *callargs, *retargs; char *p; Sym *sym; - int i; + int i, ddd; // TODO: names are not right rcvrtype = fn->left->type; @@ -309,6 +309,7 @@ makepartialcall(Node *fn, Type *t0, Node *meth) i = 0; l = nil; callargs = nil; + ddd = 0; xfunc = nod(ODCLFUNC, N, N); for(t = getinargx(t0)->type; t; t = t->down) { snprint(namebuf, sizeof namebuf, "a%d", i++); @@ -316,7 +317,12 @@ makepartialcall(Node *fn, Type *t0, Node *meth) n->class = PPARAM; xfunc->dcl = list(xfunc->dcl, n); callargs = list(callargs, n); - l = list(l, nod(ODCLFIELD, n, typenod(t->type))); + fld = nod(ODCLFIELD, n, typenod(t->type)); + if(t->isddd) { + fld->isddd = 1; + ddd = 1; + } + l = list(l, fld); } xtype->list = l; i = 0; @@ -338,7 +344,7 @@ makepartialcall(Node *fn, Type *t0, Node *meth) xfunc->nname->ntype = xtype; xfunc->nname->defn = xfunc; declare(xfunc->nname, PFUNC); - + // Declare and initialize variable holding receiver. body = nil; cv = nod(OCLOSUREVAR, N, N); @@ -362,6 +368,7 @@ makepartialcall(Node *fn, Type *t0, Node *meth) call = nod(OCALL, nod(OXDOT, ptr, meth), N); call->list = callargs; + call->isddd = ddd; if(t0->outtuple == 0) { body = list(body, call); } else { @@ -393,7 +400,7 @@ walkpartialcall(Node *n, NodeList **init) // clos = &struct{F uintptr; R T}{M.T·f, x} // // Like walkclosure above. - + if(isinter(n->left->type)) { n->left = cheapexpr(n->left, init); checknotnil(n->left, init); diff --git a/test/fixedbugs/issue5231.go b/test/fixedbugs/issue5231.go new file mode 100644 index 0000000000..4039913dc9 --- /dev/null +++ b/test/fixedbugs/issue5231.go @@ -0,0 +1,45 @@ +// compile + +// Copyright 2013 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 5231: method values lose their variadic property. + +package p + +type T int + +func (t T) NotVariadic(s []int) int { + return int(t) + s[0] +} + +func (t T) Variadic(s ...int) int { + return int(t) + s[0] +} + +type I interface { + NotVariadic(s []int) int + Variadic(s ...int) int +} + +func F() { + var t T + var p *T = &t + var i I = p + + nv := t.NotVariadic + nv = p.NotVariadic + nv = i.NotVariadic + var s int = nv([]int{1, 2, 3}) + + v := t.Variadic + v = p.Variadic + v = i.Variadic + s = v(1, 2, 3) + + var f1 func([]int) int = nv + var f2 func(...int) int = v + + _, _, _ = f1, f2, s +}