]> Cypherpunks repositories - gostls13.git/commitdiff
gc: eliminate duplicates in method table
authorRuss Cox <rsc@golang.org>
Mon, 27 Sep 2010 18:09:10 +0000 (14:09 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 27 Sep 2010 18:09:10 +0000 (14:09 -0400)
Fixes #906.

R=ken2
CC=golang-dev
https://golang.org/cl/2279042

src/cmd/gc/subr.c
src/pkg/reflect/all_test.go

index 3ba1519cf5c5f4cec0a232ae38dc7adf5fad2be0..91a012187fdb220b7fb68658009069bbbcb28dbf 100644 (file)
@@ -2935,6 +2935,11 @@ expandmeth(Sym *s, Type *t)
        if(t == T || t->xmethod != nil)
                return;
 
+       // mark top-level method symbols
+       // so that expand1 doesn't consider them.
+       for(f=t->method; f != nil; f=f->down)
+               f->sym->flags |= SymUniq;
+
        // generate all reachable methods
        slist = nil;
        expand1(t, nelem(dotlist)-1, 0);
@@ -2954,6 +2959,9 @@ expandmeth(Sym *s, Type *t)
                }
        }
 
+       for(f=t->method; f != nil; f=f->down)
+               f->sym->flags &= ~SymUniq;
+
        t->xmethod = t->method;
        for(sl=slist; sl!=nil; sl=sl->link) {
                if(sl->good) {
@@ -2965,7 +2973,6 @@ expandmeth(Sym *s, Type *t)
                                f->embedded = 2;
                        f->down = t->xmethod;
                        t->xmethod = f;
-
                }
        }
 }
index dc01890945c464d50b72b4bf1c2423a39d8a7787..61d7f2c2479344d5712d4df392f44c6654ae10c8 100644 (file)
@@ -1287,3 +1287,23 @@ func TestDotDotDot(t *testing.T) {
        }
        t.Error(s)
 }
+
+type inner struct{}
+
+type outer struct {
+       inner
+}
+
+func (*inner) m() {}
+func (*outer) m() {}
+
+func TestNestedMethods(t *testing.T) {
+       typ := Typeof((*outer)(nil))
+       if typ.NumMethod() != 1 || typ.Method(0).Func.Get() != NewValue((*outer).m).(*FuncValue).Get() {
+               t.Errorf("Wrong method table for outer: (m=%p)", (*outer).m)
+               for i := 0; i < typ.NumMethod(); i++ {
+                       m := typ.Method(i)
+                       t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Get())
+               }
+       }
+}