gc: eliminate duplicates in method table

Fixes #906.

R=ken2
CC=golang-dev
https://golang.org/cl/2279042
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 3ba1519..91a0121 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -2935,6 +2935,11 @@
 	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 @@
 		}
 	}
 
+	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 @@
 				f->embedded = 2;
 			f->down = t->xmethod;
 			t->xmethod = f;
-
 		}
 	}
 }
diff --git a/src/pkg/reflect/all_test.go b/src/pkg/reflect/all_test.go
index dc01890..61d7f2c 100644
--- a/src/pkg/reflect/all_test.go
+++ b/src/pkg/reflect/all_test.go
@@ -1287,3 +1287,23 @@
 	}
 	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())
+		}
+	}
+}