]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: fewer errors for wrong argument count
authorJan Ziak <0xe2.0x9a.0x9b@gmail.com>
Thu, 17 Apr 2014 02:42:09 +0000 (22:42 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 17 Apr 2014 02:42:09 +0000 (22:42 -0400)
Fixes #7675

LGTM=rsc
R=rsc
CC=golang-codereviews
https://golang.org/cl/85040044

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

index 7eda63bad101b6a7891150892575cb1d604223bc..d7a263722440e9af3be22098404477956483c579 100644 (file)
@@ -2167,6 +2167,31 @@ nokeys(NodeList *l)
        return 1;
 }
 
+static int
+hasddd(Type *t)
+{
+       Type *tl;
+
+       for(tl=t->type; tl; tl=tl->down) {
+               if(tl->isddd)
+                       return 1;
+       }
+       return 0;
+}
+
+static int
+downcount(Type *t)
+{
+       Type *tl;
+       int n;
+
+       n = 0;
+       for(tl=t->type; tl; tl=tl->down) {
+               n++;
+       }
+       return n;
+}
+
 /*
  * typecheck assignment: type list = expression list
  */
@@ -2177,6 +2202,7 @@ typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *
        Node *n;
        int lno;
        char *why;
+       int n1, n2;
 
        lno = lineno;
 
@@ -2186,6 +2212,15 @@ typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *
        n = N;
        if(nl != nil && nl->next == nil && (n = nl->n)->type != T)
        if(n->type->etype == TSTRUCT && n->type->funarg) {
+               if(!hasddd(tstruct)) {
+                       n1 = downcount(tstruct);
+                       n2 = downcount(n->type);
+                       if(n2 > n1)
+                               goto toomany;
+                       if(n2 < n1)
+                               goto notenough;
+               }
+               
                tn = n->type->type;
                for(tl=tstruct->type; tl; tl=tl->down) {
                        if(tl->isddd) {
@@ -2214,6 +2249,26 @@ typecheckaste(int op, Node *call, int isddd, Type *tstruct, NodeList *nl, char *
                goto out;
        }
 
+       n1 = downcount(tstruct);
+       n2 = count(nl);
+       if(!hasddd(tstruct)) {
+               if(n2 > n1)
+                       goto toomany;
+               if(n2 < n1)
+                       goto notenough;
+       }
+       else {
+               if(!isddd) {
+                       if(n2 < n1-1)
+                               goto notenough;
+               } else {
+                       if(n2 > n1)
+                               goto toomany;
+                       if(n2 < n1)
+                               goto notenough;
+               }
+       }
+
        for(tl=tstruct->type; tl; tl=tl->down) {
                t = tl->type;
                if(tl->isddd) {
diff --git a/test/fixedbugs/issue7675.go b/test/fixedbugs/issue7675.go
new file mode 100644 (file)
index 0000000..d97ee35
--- /dev/null
@@ -0,0 +1,24 @@
+// errorcheck
+
+// Copyright 2014 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 7675: fewer errors for wrong argument count
+
+package p
+
+func f(string, int, float64, string)
+
+func g(string, int, float64, ...string)
+
+func main() {
+       f(1, 0.5, "hello") // ERROR "not enough arguments"
+       f("1", 2, 3.1, "4")
+       f(1, 0.5, "hello", 4, 5) // ERROR "too many arguments"
+       g(1, 0.5)                // ERROR "not enough arguments"
+       g("1", 2, 3.1)
+       g(1, 0.5, []int{3, 4}...) // ERROR "not enough arguments"
+       g("1", 2, 3.1, "4", "5")
+       g(1, 0.5, "hello", 4, []int{5, 6}...) // ERROR "too many arguments"
+}