[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>
This commit is contained in:
Dan Scales 2021-07-25 18:27:15 -07:00
parent c751e2e6ba
commit e00a6ec084
2 changed files with 19 additions and 7 deletions

View file

@ -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 {

View file

@ -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