for !d.wq.empty() {
symIdx := d.wq.pop()
+ // Methods may be called via reflection. Give up on static analysis,
+ // and mark all exported methods of all reachable types as reachable.
d.reflectSeen = d.reflectSeen || d.ldr.IsReflectMethod(symIdx)
isgotype := d.ldr.IsGoType(symIdx)
// 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 any of:
-// - reflect.Value.Method or MethodByName is reachable
-// - reflect.Type.Method or MethodByName is called (through the
-// REFLECTMETHOD attribute marked by the compiler).
+// The third case is handled by looking for functions that compiler flagged
+// as REFLECTMETHOD. REFLECTMETHOD on a function F means that F does a method
+// lookup with reflection, but the compiler was not able to statically determine
+// the method name.
//
-// If any of these happen, all bets are off and all exported methods
-// of reachable types are marked reachable.
+// All functions that call reflect.Value.Method or reflect.Type.Method are REFLECTMETHODs.
+// Functions that call reflect.Value.MethodByName or reflect.Type.MethodByName with
+// a non-constant argument are REFLECTMETHODs, too. If we find a REFLECTMETHOD,
+// we give up on static analysis, and mark all exported methods of all reachable
+// types as reachable.
+//
+// If the argument to MethodByName is a compile-time constant, the compiler
+// emits a relocation with the method name. Matching methods are kept in all
+// reachable types.
//
// Any unreached text symbols are removed from ctxt.Textp.
func deadcode(ctxt *Link) {
d.init()
d.flood()
- methSym := ldr.Lookup("reflect.Value.Method", abiInternalVer)
- methByNameSym := ldr.Lookup("reflect.Value.MethodByName", abiInternalVer)
-
if ctxt.DynlinkingGo() {
// Exported methods may satisfy interfaces we don't know
// about yet when dynamically linking.
}
for {
- // 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)) || (methByNameSym != 0 && ldr.AttrReachable(methByNameSym))
-
// Mark all methods that could satisfy a discovered
// interface as reachable. We recheck old marked interfaces
// as new types (with new methods) may have been discovered