diff options
author | Dan Scales <danscales@google.com> | 2021-07-25 18:27:15 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-07-28 03:04:12 +0000 |
commit | e00a6ec084605b773cdb87971de5b5536c0cc13e (patch) | |
tree | 2899d6b3578ee2ee51eb25e689196d4f2325e789 | |
parent | c751e2e6ba30fc319c93b9cfe207dc7d1b48c3fb (diff) | |
download | go-e00a6ec084605b773cdb87971de5b5536c0cc13e.tar.gz go-e00a6ec084605b773cdb87971de5b5536c0cc13e.zip |
[dev.typeparams] cmd/compile: mark methods of instantiated interface types as used
Fix the cons.go missing method error. Mark all the methods of
instantiated interface types as used. We could try to record all the
exact methods used for generic interface types, but for now, just mark
all the methods as used so that their methods are not dead-code
eliminated.
Change-Id: I35685eda82476244371379b97691a1b8506ef0f7
Reviewed-on: https://go-review.googlesource.com/c/go/+/337349
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
-rw-r--r-- | src/cmd/compile/internal/noder/stencil.go | 25 | ||||
-rw-r--r-- | test/run.go | 1 |
2 files changed, 19 insertions, 7 deletions
diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index e482281a3c..02a380e63f 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -1515,6 +1515,23 @@ func deref(t *types.Type) *types.Type { return t } +// markTypeUsed marks type t as used in order to help avoid dead-code elimination of +// needed methods. +func markTypeUsed(t *types.Type, lsym *obj.LSym) { + if t.IsInterface() { + // Mark all the methods of the interface as used. + // TODO: we should really only mark the interface methods + // that are actually called in the application. + for i, _ := range t.AllMethods().Slice() { + reflectdata.MarkUsedIfaceMethodIndex(lsym, t, i) + } + } else { + // TODO: This is somewhat overkill, we really only need it + // for types that are put into interfaces. + reflectdata.MarkTypeUsedInInterface(t, lsym) + } +} + // getDictionarySym returns the dictionary for the named generic function gf, which // is instantiated with the type arguments targs. func (g *irgen) getDictionarySym(gf *ir.Name, targs []*types.Type, isMeth bool) *types.Sym { @@ -1543,11 +1560,7 @@ func (g *irgen) getDictionarySym(gf *ir.Name, targs []*types.Type, isMeth bool) infoPrint(" * %v\n", t) s := reflectdata.TypeLinksym(t) off = objw.SymPtr(lsym, off, s, 0) - // Ensure that methods on t don't get deadcode eliminated - // by the linker. - // TODO: This is somewhat overkill, we really only need it - // for types that are put into interfaces. - reflectdata.MarkTypeUsedInInterface(t, lsym) + markTypeUsed(t, lsym) } subst := typecheck.Tsubster{ Tparams: info.tparams, @@ -1559,7 +1572,7 @@ func (g *irgen) getDictionarySym(gf *ir.Name, targs []*types.Type, isMeth bool) infoPrint(" - %v\n", ts) s := reflectdata.TypeLinksym(ts) off = objw.SymPtr(lsym, off, s, 0) - reflectdata.MarkTypeUsedInInterface(ts, lsym) + markTypeUsed(ts, lsym) } // Emit an entry for each subdictionary (after substituting targs) for _, n := range info.subDictCalls { diff --git a/test/run.go b/test/run.go index edf26a5d82..4971043ab6 100644 --- a/test/run.go +++ b/test/run.go @@ -2181,7 +2181,6 @@ var g3Failures = setOf( "fixedbugs/issue30862.go", // -G=3 doesn't handle //go:nointerface - "typeparam/cons.go", // causes an unreachable method "typeparam/nested.go", // -G=3 doesn't support function-local types with generics "typeparam/mdempsky/4.go", // -G=3 can't export functions with labeled breaks in loops |