From 4c052844dd74f6be5401d343405ba5560dc95fdd Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 7 Mar 2011 19:36:17 -0500 Subject: [PATCH] gc: fix handling of return values named _ Fixes #1586. R=ken2 CC=golang-dev https://golang.org/cl/4244057 --- src/cmd/gc/dcl.c | 29 ++++++++++++++-------------- test/fixedbugs/bug326.go | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 14 deletions(-) create mode 100644 test/fixedbugs/bug326.go diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index 2aa1bc81701..cbcdcbf8c70 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -693,13 +693,13 @@ ok: * turn a parsed struct into a type */ static Type** -stotype(NodeList *l, int et, Type **t) +stotype(NodeList *l, int et, Type **t, int funarg) { Type *f, *t1, *t2, **t0; Strlit *note; int lno; NodeList *init; - Node *n; + Node *n, *left; char *what; t0 = t; @@ -716,15 +716,18 @@ stotype(NodeList *l, int et, Type **t) if(n->op != ODCLFIELD) fatal("stotype: oops %N\n", n); + left = n->left; + if(funarg && isblank(left)) + left = N; if(n->right != N) { - if(et == TINTER && n->left != N) { + if(et == TINTER && left != N) { // queue resolution of method type for later. // right now all we need is the name list. // avoids cycles for recursive interface types. n->type = typ(TINTERMETH); n->type->nname = n->right; n->right = N; - n->left->type = n->type; + left->type = n->type; queuemethod(n); } else { typecheck(&n->right, Etype); @@ -733,8 +736,8 @@ stotype(NodeList *l, int et, Type **t) *t0 = T; return t0; } - if(n->left != N) - n->left->type = n->type; + if(left != N) + left->type = n->type; n->right = N; if(n->embedded && n->type != T) { t1 = n->type; @@ -772,7 +775,7 @@ stotype(NodeList *l, int et, Type **t) break; } - if(et == TINTER && n->left == N) { + if(et == TINTER && left == N) { // embedded interface - inline the methods if(n->type->etype != TINTER) { if(n->type->etype == TFORW) @@ -805,8 +808,8 @@ stotype(NodeList *l, int et, Type **t) f->width = BADWIDTH; f->isddd = n->isddd; - if(n->left != N && n->left->op == ONAME) { - f->nname = n->left; + if(left != N && left->op == ONAME) { + f->nname = left; f->embedded = n->embedded; f->sym = f->nname->sym; if(importpkg && !exportname(f->sym->name)) @@ -848,7 +851,7 @@ dostruct(NodeList *l, int et) } t = typ(et); t->funarg = funarg; - stotype(l, et, &t->type); + stotype(l, et, &t->type, funarg); if(t->type == T && l != nil) { t->broke = 1; return t; @@ -942,8 +945,6 @@ checkarglist(NodeList *all, int input) t = n; n = N; } - if(isblank(n)) - n = N; if(n != N && n->sym == S) { t = n; n = N; @@ -1160,9 +1161,9 @@ addmethod(Sym *sf, Type *t, int local) } if(d == T) - stotype(list1(n), 0, &pa->method); + stotype(list1(n), 0, &pa->method, 0); else - stotype(list1(n), 0, &d->down); + stotype(list1(n), 0, &d->down, 0); return; } diff --git a/test/fixedbugs/bug326.go b/test/fixedbugs/bug326.go new file mode 100644 index 00000000000..efdd0ef7131 --- /dev/null +++ b/test/fixedbugs/bug326.go @@ -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 +}