mirror of
https://github.com/golang/go
synced 2024-11-05 18:36:08 +00:00
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
This commit is contained in:
parent
18ca86ebb3
commit
20e05303fe
2 changed files with 57 additions and 5 deletions
|
@ -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);
|
||||
|
|
45
test/fixedbugs/issue5231.go
Normal file
45
test/fixedbugs/issue5231.go
Normal file
|
@ -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
|
||||
}
|
Loading…
Reference in a new issue