summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorR?my Oudompheng <oudomphe@phare.normalesup.org>2013-08-29 10:00:58 +0200
committerR?my Oudompheng <oudomphe@phare.normalesup.org>2013-08-29 10:00:58 +0200
commita4a227de62bb382fcd736bb15e7c785912be983b (patch)
tree3eee07d104cdc6e1676795e9ebace6d21c675731
parent19117c3c362839d0bd1fc40329f26ae925eb5f08 (diff)
downloadgo-a4a227de62bb382fcd736bb15e7c785912be983b.tar.gz
cmd/gc: fix method values whose receiver is an unnamed interface.
Fixes issue 6140. R=golang-dev, iant CC=golang-dev https://codereview.appspot.com/13083043
-rw-r--r--src/cmd/gc/closure.c14
-rw-r--r--test/fixedbugs/issue6140.go31
-rw-r--r--test/method2.go5
3 files changed, 46 insertions, 4 deletions
diff --git a/src/cmd/gc/closure.c b/src/cmd/gc/closure.c
index 8c40cb8d9..5a84dfb1b 100644
--- a/src/cmd/gc/closure.c
+++ b/src/cmd/gc/closure.c
@@ -285,6 +285,8 @@ makepartialcall(Node *fn, Type *t0, Node *meth)
NodeList *body, *l, *callargs, *retargs;
char *p;
Sym *sym;
+ Pkg *spkg;
+ static Pkg* gopkg;
int i, ddd;
// TODO: names are not right
@@ -296,10 +298,18 @@ makepartialcall(Node *fn, Type *t0, Node *meth)
basetype = rcvrtype;
if(isptr[rcvrtype->etype])
basetype = basetype->type;
- if(basetype->sym == S)
+ if(basetype->etype != TINTER && basetype->sym == S)
fatal("missing base type for %T", rcvrtype);
- sym = pkglookup(p, basetype->sym->pkg);
+ spkg = nil;
+ if(basetype->sym != S)
+ spkg = basetype->sym->pkg;
+ if(spkg == nil) {
+ if(gopkg == nil)
+ gopkg = mkpkg(strlit("go"));
+ spkg = gopkg;
+ }
+ sym = pkglookup(p, spkg);
free(p);
if(sym->flags & SymUniq)
return sym->def;
diff --git a/test/fixedbugs/issue6140.go b/test/fixedbugs/issue6140.go
new file mode 100644
index 000000000..d494933b2
--- /dev/null
+++ b/test/fixedbugs/issue6140.go
@@ -0,0 +1,31 @@
+// compile
+
+// Copyright 2013 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 6140: compiler incorrectly rejects method values
+// whose receiver has an unnamed interface type.
+
+package p
+
+type T *interface {
+ m() int
+}
+
+var x T
+
+var _ = (*x).m
+
+var y interface {
+ m() int
+}
+
+var _ = y.m
+
+type I interface {
+ String() string
+}
+
+var z *struct{ I }
+var _ = z.String
diff --git a/test/method2.go b/test/method2.go
index b63da10dc..aaa850e71 100644
--- a/test/method2.go
+++ b/test/method2.go
@@ -21,7 +21,7 @@ func (p *P1) val() int { return 1 } // ERROR "receiver.* pointer|invalid pointer
type I interface{}
type I1 interface{}
-func (p I) val() int { return 1 } // ERROR "receiver.*interface|invalid pointer or interface receiver"
+func (p I) val() int { return 1 } // ERROR "receiver.*interface|invalid pointer or interface receiver"
func (p *I1) val() int { return 1 } // ERROR "receiver.*interface|invalid pointer or interface receiver"
type Val interface {
@@ -33,4 +33,5 @@ var _ = (*Val).val // ERROR "method"
var v Val
var pv = &v
-var _ = pv.val() // ERROR "method"
+var _ = pv.val() // ERROR "method"
+var _ = pv.val // ERROR "method"