aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/typecheck/crawler.go
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2021-09-18 20:02:08 -0700
committerDan Scales <danscales@google.com>2021-09-24 18:21:14 +0000
commitf6b5ffb5e1d31fd24edadfe6c105886093638825 (patch)
tree0dcabfd533af81963f3c6a7be586ca2b2444efc7 /src/cmd/compile/internal/typecheck/crawler.go
parent812c99f86a1b38d50c5c0b501d10b72c3b7dfb95 (diff)
downloadgo-f6b5ffb5e1d31fd24edadfe6c105886093638825.tar.gz
go-f6b5ffb5e1d31fd24edadfe6c105886093638825.zip
cmd/compile: fix crawler for unexported fields with instantiated types
In markType() in crawler.go, mark the type of a unexported field if it is a fully-instantiated type, since we create and instantiate the methods of any fully-instantiated type that we see during import. As before, we still do not mark the type of an unexported field if that type is not generic. Fixes #48454 and most recent issue described in 48337. The included test is similar to the case in 48454. Fixes #48454 Fixes #48337 Change-Id: I77a2a62b9e2647876facfa6f004201e8f699c905 Reviewed-on: https://go-review.googlesource.com/c/go/+/351315 Trust: Dan Scales <danscales@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/typecheck/crawler.go')
-rw-r--r--src/cmd/compile/internal/typecheck/crawler.go28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/cmd/compile/internal/typecheck/crawler.go b/src/cmd/compile/internal/typecheck/crawler.go
index 3f212aa805..667e76e130 100644
--- a/src/cmd/compile/internal/typecheck/crawler.go
+++ b/src/cmd/compile/internal/typecheck/crawler.go
@@ -10,10 +10,12 @@ import (
"cmd/compile/internal/types"
)
-// crawlExports crawls the type/object graph rooted at the given list
-// of exported objects. Any functions that are found to be potentially
-// callable by importers are marked with ExportInline so that
-// iexport.go knows to re-export their inline body.
+// crawlExports crawls the type/object graph rooted at the given list of exported
+// objects. It descends through all parts of types and follows any methods on defined
+// types. Any functions that are found to be potentially callable by importers are
+// marked with ExportInline, so that iexport.go knows to re-export their inline body.
+// Also, any function or global referenced by a function marked by ExportInline() is
+// marked for export (whether its name is exported or not).
func crawlExports(exports []*ir.Name) {
p := crawler{
marked: make(map[*types.Type]bool),
@@ -29,7 +31,7 @@ type crawler struct {
embedded map[*types.Type]bool // types already seen by markEmbed
}
-// markObject visits a reachable object.
+// markObject visits a reachable object (function, method, global type, or global variable)
func (p *crawler) markObject(n *ir.Name) {
if n.Op() == ir.ONAME && n.Class == ir.PFUNC {
p.markInlBody(n)
@@ -97,7 +99,12 @@ func (p *crawler) markType(t *types.Type) {
break
}
for _, f := range t.FieldSlice() {
- if types.IsExported(f.Sym.Name) || f.Embedded != 0 {
+ // Mark the type of a unexported field if it is a
+ // fully-instantiated type, since we create and instantiate
+ // the methods of any fully-instantiated type that we see
+ // during import (see end of typecheck.substInstType).
+ if types.IsExported(f.Sym.Name) || f.Embedded != 0 ||
+ isPtrFullyInstantiated(f.Type) {
p.markType(f.Type)
}
}
@@ -108,8 +115,6 @@ func (p *crawler) markType(t *types.Type) {
}
case types.TINTER:
- // TODO(danscales) - will have to deal with the types in interface
- // elements here when implemented in types2 and represented in types1.
for _, f := range t.AllMethods().Slice() {
if types.IsExported(f.Sym.Name) {
p.markType(f.Type)
@@ -226,3 +231,10 @@ func (p *crawler) markInlBody(n *ir.Name) {
// because after inlining they might be callable.
ir.VisitList(fn.Inl.Body, doFlood)
}
+
+// isPtrFullyInstantiated returns true if t is a fully-instantiated type, or it is a
+// pointer to a fully-instantiated type.
+func isPtrFullyInstantiated(t *types.Type) bool {
+ return t.IsPtr() && t.Elem().IsFullyInstantiated() ||
+ t.IsFullyInstantiated()
+}