]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/link: check for reflect.Value.MethodByName explicitly
authorCherry Zhang <cherryyz@google.com>
Sun, 19 Apr 2020 03:08:36 +0000 (23:08 -0400)
committerCherry Zhang <cherryyz@google.com>
Sun, 19 Apr 2020 03:23:59 +0000 (03:23 +0000)
Currently we only check for reflect.Value.Method. And
reflect.Value.MethodByName is covered since it calls
reflect.Value.Method internally. But it is brittle to rely on
implementation detail of the reflect package. Check for
MethodByName explicitly.

Change-Id: Ifa8920e997524003dade03abc4fb3c4e64723643
Reviewed-on: https://go-review.googlesource.com/c/go/+/228881
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/link/internal/ld/deadcode.go
src/cmd/link/internal/ld/deadcode2.go

index b5bc50835660f3cef405e9a6f2c9315bac352fc6..ae676935fc0bccd2954a5a7e40757385bd5b3667 100644 (file)
@@ -22,7 +22,8 @@ import (
 //
 //     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.
@@ -33,7 +34,7 @@ import (
 // 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
index 1aa65aee7877e65445a12020e1b05cfda0bd57d6..93df626c21574f9f5e4abc77e244b4aa0f8f4c10 100644 (file)
@@ -220,6 +220,7 @@ func deadcode2(ctxt *Link) {
        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.
@@ -230,7 +231,7 @@ func deadcode2(ctxt *Link) {
                // 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