//
// 1. direct call
// 2. through a reachable interface type
-// 3. reflect.Value.Method, or reflect.Type.Method
+// 3. reflect.Value.Method (or MethodByName), or reflect.Type.Method
+// (or MethodByName)
//
// The first case is handled by the flood fill, a directly called method
// is marked as reachable.
// as reachable. This is extremely conservative, but easy and correct.
//
// The third case is handled by looking to see if any of:
-// - reflect.Value.Method is reachable
+// - reflect.Value.Method or MethodByName is reachable
// - reflect.Type.Method or MethodByName is called (through the
// REFLECTMETHOD attribute marked by the compiler).
// If any of these happen, all bets are off and all exported methods
d.flood()
methSym := ldr.Lookup("reflect.Value.Method", sym.SymVerABIInternal)
+ methByNameSym := ldr.Lookup("reflect.Value.MethodByName", sym.SymVerABIInternal)
if ctxt.DynlinkingGo() {
// Exported methods may satisfy interfaces we don't know
// about yet when dynamically linking.
// Methods might be called via reflection. Give up on
// static analysis, mark all exported methods of
// all reachable types as reachable.
- d.reflectSeen = d.reflectSeen || (methSym != 0 && ldr.AttrReachable(methSym))
+ d.reflectSeen = d.reflectSeen || (methSym != 0 && ldr.AttrReachable(methSym)) || (methByNameSym != 0 && ldr.AttrReachable(methByNameSym))
// Mark all methods that could satisfy a discovered
// interface as reachable. We recheck old marked interfaces