1
0
mirror of https://github.com/golang/go synced 2024-11-21 18:34:44 -07:00

gc: fix handling of return values named _

Fixes #1586.

R=ken2
CC=golang-dev
https://golang.org/cl/4244057
This commit is contained in:
Russ Cox 2011-03-07 19:36:17 -05:00
parent fb64e0d96f
commit 4c052844dd
2 changed files with 56 additions and 14 deletions

View File

@ -693,13 +693,13 @@ ok:
* turn a parsed struct into a type * turn a parsed struct into a type
*/ */
static Type** static Type**
stotype(NodeList *l, int et, Type **t) stotype(NodeList *l, int et, Type **t, int funarg)
{ {
Type *f, *t1, *t2, **t0; Type *f, *t1, *t2, **t0;
Strlit *note; Strlit *note;
int lno; int lno;
NodeList *init; NodeList *init;
Node *n; Node *n, *left;
char *what; char *what;
t0 = t; t0 = t;
@ -716,15 +716,18 @@ stotype(NodeList *l, int et, Type **t)
if(n->op != ODCLFIELD) if(n->op != ODCLFIELD)
fatal("stotype: oops %N\n", n); fatal("stotype: oops %N\n", n);
left = n->left;
if(funarg && isblank(left))
left = N;
if(n->right != N) { if(n->right != N) {
if(et == TINTER && n->left != N) { if(et == TINTER && left != N) {
// queue resolution of method type for later. // queue resolution of method type for later.
// right now all we need is the name list. // right now all we need is the name list.
// avoids cycles for recursive interface types. // avoids cycles for recursive interface types.
n->type = typ(TINTERMETH); n->type = typ(TINTERMETH);
n->type->nname = n->right; n->type->nname = n->right;
n->right = N; n->right = N;
n->left->type = n->type; left->type = n->type;
queuemethod(n); queuemethod(n);
} else { } else {
typecheck(&n->right, Etype); typecheck(&n->right, Etype);
@ -733,8 +736,8 @@ stotype(NodeList *l, int et, Type **t)
*t0 = T; *t0 = T;
return t0; return t0;
} }
if(n->left != N) if(left != N)
n->left->type = n->type; left->type = n->type;
n->right = N; n->right = N;
if(n->embedded && n->type != T) { if(n->embedded && n->type != T) {
t1 = n->type; t1 = n->type;
@ -772,7 +775,7 @@ stotype(NodeList *l, int et, Type **t)
break; break;
} }
if(et == TINTER && n->left == N) { if(et == TINTER && left == N) {
// embedded interface - inline the methods // embedded interface - inline the methods
if(n->type->etype != TINTER) { if(n->type->etype != TINTER) {
if(n->type->etype == TFORW) if(n->type->etype == TFORW)
@ -805,8 +808,8 @@ stotype(NodeList *l, int et, Type **t)
f->width = BADWIDTH; f->width = BADWIDTH;
f->isddd = n->isddd; f->isddd = n->isddd;
if(n->left != N && n->left->op == ONAME) { if(left != N && left->op == ONAME) {
f->nname = n->left; f->nname = left;
f->embedded = n->embedded; f->embedded = n->embedded;
f->sym = f->nname->sym; f->sym = f->nname->sym;
if(importpkg && !exportname(f->sym->name)) if(importpkg && !exportname(f->sym->name))
@ -848,7 +851,7 @@ dostruct(NodeList *l, int et)
} }
t = typ(et); t = typ(et);
t->funarg = funarg; t->funarg = funarg;
stotype(l, et, &t->type); stotype(l, et, &t->type, funarg);
if(t->type == T && l != nil) { if(t->type == T && l != nil) {
t->broke = 1; t->broke = 1;
return t; return t;
@ -942,8 +945,6 @@ checkarglist(NodeList *all, int input)
t = n; t = n;
n = N; n = N;
} }
if(isblank(n))
n = N;
if(n != N && n->sym == S) { if(n != N && n->sym == S) {
t = n; t = n;
n = N; n = N;
@ -1160,9 +1161,9 @@ addmethod(Sym *sf, Type *t, int local)
} }
if(d == T) if(d == T)
stotype(list1(n), 0, &pa->method); stotype(list1(n), 0, &pa->method, 0);
else else
stotype(list1(n), 0, &d->down); stotype(list1(n), 0, &d->down, 0);
return; return;
} }

41
test/fixedbugs/bug326.go Normal file
View File

@ -0,0 +1,41 @@
// errchk $G $D/$F.go
// Copyright 2011 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 p
import "os"
func f() (_ int, err os.Error) {
return
}
func g() (x int, _ os.Error) {
return
}
func h() (_ int, _ os.Error) {
return
}
func i() (int, os.Error) {
return // ERROR "not enough arguments to return"
}
func f1() (_ int, err os.Error) {
return 1, nil
}
func g1() (x int, _ os.Error) {
return 1, nil
}
func h1() (_ int, _ os.Error) {
return 1, nil
}
func ii() (int, os.Error) {
return 1, nil
}