]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: properly set variadic flag on method values.
authorRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 8 Apr 2013 06:59:33 +0000 (08:59 +0200)
committerRémy Oudompheng <oudomphe@phare.normalesup.org>
Mon, 8 Apr 2013 06:59:33 +0000 (08:59 +0200)
Fixes #5231.

R=golang-dev, daniel.morsing, adg
CC=golang-dev
https://golang.org/cl/8275044

src/cmd/gc/closure.c
test/fixedbugs/issue5231.go [new file with mode: 0644]

index c1a9eb14cc6eb72c2e8601d7eece9d3c7ce6ca3c..962b08845206fd0584e25c6b270121dc64d6664e 100644 (file)
@@ -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 (file)
index 0000000..4039913
--- /dev/null
@@ -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
+}