aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-07-25 18:27:15 -0700
committerDan Scales <danscales@google.com>2021-07-28 03:04:12 +0000
commite00a6ec084605b773cdb87971de5b5536c0cc13e (patch)
tree2899d6b3578ee2ee51eb25e689196d4f2325e789
parentc751e2e6ba30fc319c93b9cfe207dc7d1b48c3fb (diff)
downloadgo-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.go25
-rw-r--r--test/run.go1
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