diff options
author | Dan Scales <danscales@google.com> | 2021-09-18 20:02:08 -0700 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-09-24 18:21:14 +0000 |
commit | f6b5ffb5e1d31fd24edadfe6c105886093638825 (patch) | |
tree | 0dcabfd533af81963f3c6a7be586ca2b2444efc7 /src/cmd/compile/internal/typecheck/crawler.go | |
parent | 812c99f86a1b38d50c5c0b501d10b72c3b7dfb95 (diff) | |
download | go-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.go | 28 |
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() +} |