1
0
mirror of https://github.com/golang/go synced 2024-11-19 01:24:39 -07:00

cmd/compile: do not flag reflect.StructOf() as a ReflectMethod.

StructOf() calls reflect.Type.Method(), but looks up only methods
accessible via interfaces. DCE does not remove such methods, so
there is no need to disable the DCE if StructOf() is used.

There is a dependency chain between struct rtype and StructOf():

  (*rtype).Method() -> FuncOf() -> initFuncTypes() -> StructOf().

Thus, any use of (*rtype).Method() or (*rtype).MethodByName()
disables the DCE in the linker. This is not an issue just yet
because all users of Method() and MethodByName() are flagged
as ReflectMethods. A subsequent patch avoids this flag on callers
of MethodByName(string literal). When that patch is applied,
it becomes important to have no ReflectMethods down the call
chain of MethodByName().

Change-Id: I9b3e55c495c122ed70ef31f9d978c0e2e0573799
Reviewed-on: https://go-review.googlesource.com/c/go/+/522435
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Joedian Reid <joedian@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Dominique Lefevre 2023-08-24 10:14:54 +03:00 committed by Cherry Mui
parent 111ab75432
commit 07faf8fab5

View File

@ -951,8 +951,17 @@ func usemethod(n *ir.CallExpr) {
// Those functions may be alive via the itab, which should not cause all methods
// alive. We only want to mark their callers.
if base.Ctxt.Pkgpath == "reflect" {
switch ir.CurFunc.Nname.Sym().Name { // TODO: is there a better way than hardcoding the names?
case "(*rtype).Method", "(*rtype).MethodByName", "(*interfaceType).Method", "(*interfaceType).MethodByName":
// TODO: is there a better way than hardcoding the names?
switch fn := ir.CurFunc.Nname.Sym().Name; {
case fn == "(*rtype).Method", fn == "(*rtype).MethodByName":
return
case fn == "(*interfaceType).Method", fn == "(*interfaceType).MethodByName":
return
// StructOf defines closures that look up methods. They only look up methods
// reachable via interfaces. The DCE does not remove such methods. It is ok
// to not flag closures in StructOf as ReflectMethods and let the DCE run
// even if StructOf is reachable.
case strings.HasPrefix(fn, "StructOf.func"):
return
}
}