diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c index 7eda63bad10..d7a26372244 100644 --- a/src/cmd/gc/typecheck.c +++ b/src/cmd/gc/typecheck.c @@ -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 index 00000000000..d97ee357a22 --- /dev/null +++ b/test/fixedbugs/issue7675.go @@ -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" +}