--- /dev/null
+// +build ignore
+
+package main
+
+// Test of interface calls.
+
+func use(interface{})
+
+type A byte // instantiated but not a reflect type
+
+func (A) f() {} // called directly
+func (A) F() {} // unreachable
+
+type B int // a reflect type
+
+func (*B) f() {} // reachable via interface invoke
+func (*B) F() {} // reachable: exported method of reflect type
+
+type B2 int // a reflect type, and *B2 also
+
+func (B2) f() {} // reachable via interface invoke
+func (B2) g() {} // reachable: exported method of reflect type
+
+type C string // not instantiated
+
+func (C) f() {} // unreachable
+func (C) F() {} // unreachable
+
+type D uint // instantiated only in dead code
+
+func (D) f() {} // unreachable
+func (D) F() {} // unreachable
+
+func main() {
+ A(0).f()
+
+ use(new(B))
+ use(B2(0))
+
+ var i interface {
+ f()
+ }
+ i.f() // calls (*B).f, (*B2).f and (B2.f)
+
+ live()
+}
+
+func live() {
+ var j interface {
+ f()
+ g()
+ }
+ j.f() // calls (B2).f and (*B2).f but not (*B).f (no g method).
+}
+
+func dead() {
+ use(D(0))
+}
+
+// WANT:
+// Dynamic calls
+// live --> (*B2).f
+// live --> (B2).f
+// main --> (*B).f
+// main --> (*B2).f
+// main --> (B2).f
+// Reachable functions
+// (*B).F
+// (*B).f
+// (*B2).f
+// (A).f
+// (B2).f
+// live
+// use
+// Reflect types
+// *B
+// *B2
+// B
+// B2