]> Cypherpunks repositories - gostls13.git/commitdiff
gc: double-check usage of ...
authorRuss Cox <rsc@golang.org>
Tue, 15 Dec 2009 22:26:50 +0000 (14:26 -0800)
committerRuss Cox <rsc@golang.org>
Tue, 15 Dec 2009 22:26:50 +0000 (14:26 -0800)
Fixes #423.

R=ken2
https://golang.org/cl/180045

src/cmd/gc/dcl.c
src/cmd/gc/go.h
src/cmd/gc/go.y
test/fixedbugs/bug228.go [new file with mode: 0644]

index 338a6213a688a4d73aedd3c937b3ef4d2395c2aa..e17ccfb22eb939670a85f09a802d6ac68586a396 100644 (file)
@@ -961,7 +961,7 @@ findtype(NodeList *l)
 }
 
 NodeList*
-checkarglist(NodeList *all)
+checkarglist(NodeList *all, int input)
 {
        int named;
        Node *n, *t, *nextt;
@@ -1015,8 +1015,12 @@ checkarglist(NodeList *all)
                if(n != N)
                        n = newname(n->sym);
                n = nod(ODCLFIELD, n, t);
-               if(l->next != nil && n->right != N && n->right->op == OTYPE && isddd(n->right->type))
-                       yyerror("only last argument can have type ...");
+               if(n->right != N && n->right->op == OTYPE && isddd(n->right->type)) {
+                       if(!input)
+                               yyerror("cannot use ... in output argument list");
+                       else if(l->next != nil)
+                               yyerror("can only use ... as final argument in list");
+               }
                l->n = n;
        }
        return all;
index b1378af4c8e247f16123006083b08d3e4b0fbc48..692dc77bfc3557aa32c36e7a685f753b8e22ebf3 100644 (file)
@@ -955,7 +955,7 @@ Type*       newtype(Sym*);
 Type*  oldtype(Sym*);
 void   fninit(NodeList*);
 Node*  nametodcl(Node*, Type*);
-NodeList*      checkarglist(NodeList*);
+NodeList*      checkarglist(NodeList*, int);
 void   checkwidth(Type*);
 void   defercheckwidth(void);
 void   resumecheckwidth(void);
index 2fd36e751e82d08e188c56f7d5315db9cf48a49a..a8b921db5a23f756387fff5f0cd34f7f65a3dbd9 100644 (file)
@@ -1070,6 +1070,7 @@ fndcl:
        {
                Node *n;
 
+               $3 = checkarglist($3, 1);
                $$ = nod(ODCLFUNC, N, N);
                $$->nname = $1;
                if($3 == nil && $5 == nil)
@@ -1085,6 +1086,8 @@ fndcl:
        {
                Node *rcvr, *t;
 
+               $2 = checkarglist($2, 0);
+               $6 = checkarglist($6, 1);
                $$ = N;
                if($2 == nil) {
                        yyerror("method has no receiver");
@@ -1113,6 +1116,7 @@ fndcl:
 fntype:
        LFUNC '(' oarg_type_list_ocomma ')' fnres
        {
+               $3 = checkarglist($3, 1);
                $$ = nod(OTFUNC, N, N);
                $$->list = $3;
                $$->rlist = $5;
@@ -1140,6 +1144,7 @@ fnres:
        }
 |      '(' oarg_type_list_ocomma ')'
        {
+               $2 = checkarglist($2, 0);
                $$ = $2;
        }
 
@@ -1280,6 +1285,7 @@ indcl:
        '(' oarg_type_list_ocomma ')' fnres
        {
                // without func keyword
+               $2 = checkarglist($2, 0);
                $$ = nod(OTFUNC, fakethis(), N);
                $$->list = $2;
                $$->rlist = $4;
@@ -1320,7 +1326,7 @@ oarg_type_list_ocomma:
        }
 |      arg_type_list ocomma
        {
-               $$ = checkarglist($1);
+               $$ = $1;
        }
 
 /*
diff --git a/test/fixedbugs/bug228.go b/test/fixedbugs/bug228.go
new file mode 100644 (file)
index 0000000..682152e
--- /dev/null
@@ -0,0 +1,19 @@
+// errchk $G -e $D/$F.go
+
+// Copyright 2009 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.
+
+package main
+
+func f(x int, y ...)   // ok
+
+func g(x int, y float) (...)   // ERROR "[.][.][.]"
+
+func h(x, y ...)               // ERROR "[.][.][.]"
+
+func i(x int, y ..., z float)  // ERROR "[.][.][.]"
+
+var x ...;             // ERROR "[.][.][.]|syntax"
+
+type T ...;            // ERROR "[.][.][.]|syntax"