//
 //     1. direct call
 //     2. through a reachable interface type
-//     3. reflect.Value.Call / reflect.Method.Func
+//     3. reflect.Value.Call, .Method, or reflect.Method.Func
 //
 // The first case is handled by the flood fill, a directly called method
 // is marked as reachable.
 // against the interface method signatures, if it matches it is marked
 // as reachable. This is extremely conservative, but easy and correct.
 //
-// The third case is handled by looking to see if reflect.Value.Call is
-// ever marked reachable, or if a reflect.Method struct is ever
-// constructed by a call to reflect.Type.Method or MethodByName. If it
-// is, all bets are off and all exported methods of reachable types are
-// marked reachable.
+// The third case is handled by looking to see if any of:
+//     - reflect.Value.Call is reachable
+//     - reflect.Value.Method is reachable
+//     - reflect.Type.Method or MethodByName is called.
+// If any of these happen, all bets are off and all exported methods
+// of reachable types are marked reachable.
 //
 // Any unreached text symbols are removed from ctxt.Textp.
 func deadcode(ctxt *Link) {
        d.flood()
 
        callSym := Linkrlookup(ctxt, "reflect.Value.Call", 0)
-       callSymSeen := false
+       methSym := Linkrlookup(ctxt, "reflect.Value.Method", 0)
+       reflectSeen := false
 
        for {
-               if callSym != nil && (callSym.Attr.Reachable() || d.reflectMethod) {
-                       // Methods are called via reflection. Give up on
-                       // static analysis, mark all exported methods of
-                       // all reachable types as reachable.
-                       callSymSeen = true
+               if !reflectSeen {
+                       if d.reflectMethod || (callSym != nil && callSym.Attr.Reachable()) || (methSym != nil && methSym.Attr.Reachable()) {
+                               // Methods might be called via reflection. Give up on
+                               // static analysis, mark all exported methods of
+                               // all reachable types as reachable.
+                               reflectSeen = true
+                       }
                }
 
                // Mark all methods that could satisfy a discovered
                // in the last pass.
                var rem []methodref
                for _, m := range d.markableMethods {
-                       if (callSymSeen && m.isExported()) || d.ifaceMethod[m.m] {
+                       if (reflectSeen && m.isExported()) || d.ifaceMethod[m.m] {
                                d.markMethod(m)
                        } else {
                                rem = append(rem, m)
 
--- /dev/null
+// run
+
+// Copyright 2016 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.
+
+// The linker can prune methods that are not directly called or
+// assigned to interfaces, but only if reflect.Value.Method is
+// never used. Test it here.
+
+package main
+
+import "reflect"
+
+var called = false
+
+type M int
+
+func (m M) UniqueMethodName() {
+       called = true
+}
+
+var v M
+
+func main() {
+       reflect.ValueOf(v).Method(0).Interface().(func())()
+       if !called {
+               panic("UniqueMethodName not called")
+       }
+}