From 9fa85518ff84420af644b1dd82ff311a39cd99c1 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Mon, 18 Oct 2021 12:19:07 -0700 Subject: [PATCH] cmd/compile: substitute "". prefix with package in more import locations The "" stand-in for the current package needs to be substituted in more places when importing, because of generics. ""..dict.conv4["".MyString] when imported in main and then exported, this becomes a..dict.conv4["".MyString] and then the linker makes that into a..dict.conv4[main.MyString] Which isn't correct. We need to replace on import not just function names, but also globals, which this CL does. Change-Id: Ia04a23b5ffd60aeeaba72c807f69261105670f8e Reviewed-on: https://go-review.googlesource.com/c/go/+/356570 Trust: Keith Randall Trust: Dan Scales Run-TryBot: Keith Randall TryBot-Result: Go Bot Reviewed-by: Dan Scales --- src/cmd/compile/internal/typecheck/iimport.go | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/cmd/compile/internal/typecheck/iimport.go b/src/cmd/compile/internal/typecheck/iimport.go index 52236ce837..6351fc37de 100644 --- a/src/cmd/compile/internal/typecheck/iimport.go +++ b/src/cmd/compile/internal/typecheck/iimport.go @@ -176,7 +176,7 @@ func ReadImports(pkg *types.Pkg, data string) { } for nSyms := ird.uint64(); nSyms > 0; nSyms-- { - s := pkg.Lookup(p.stringAt(ird.uint64())) + s := pkg.Lookup(p.nameAt(ird.uint64())) off := ird.uint64() if _, ok := DeclImporter[s]; !ok { @@ -188,18 +188,9 @@ func ReadImports(pkg *types.Pkg, data string) { // Inline body index. for nPkgs := ird.uint64(); nPkgs > 0; nPkgs-- { pkg := p.pkgAt(ird.uint64()) - pkgPrefix := pkg.Prefix + "." for nSyms := ird.uint64(); nSyms > 0; nSyms-- { - s2 := p.stringAt(ird.uint64()) - // Function/method instantiation names may include "" to - // represent the path name of the imported package (in type - // names), so replace "" with pkg.Prefix. The "" in the names - // will get replaced by the linker as well, so will not - // appear in the executable. Include the dot to avoid - // matching with struct tags ending in '"'. - s2 = strings.Replace(s2, "\"\".", pkgPrefix, -1) - s := pkg.Lookup(s2) + s := pkg.Lookup(p.nameAt(ird.uint64())) off := ird.uint64() if _, ok := inlineImporter[s]; !ok { @@ -233,6 +224,22 @@ func (p *iimporter) stringAt(off uint64) string { return p.stringData[spos : spos+slen] } +// nameAt is the same as stringAt, except it replaces instances +// of "" with the path of the package being imported. +func (p *iimporter) nameAt(off uint64) string { + s := p.stringAt(off) + // Names of objects (functions, methods, globals) may include "" + // to represent the path name of the imported package. + // Replace "" with the imported package prefix. This occurs + // specifically for generics where the names of instantiations + // and dictionaries contain package-qualified type names. + // Include the dot to avoid matching with struct tags ending in '"'. + if strings.Contains(s, "\"\".") { + s = strings.Replace(s, "\"\".", p.ipkg.Prefix+".", -1) + } + return s +} + func (p *iimporter) posBaseAt(off uint64) *src.PosBase { if posBase, ok := p.posBaseCache[off]; ok { return posBase @@ -288,6 +295,7 @@ func (p *iimporter) newReader(off uint64, pkg *types.Pkg) *importReader { } func (r *importReader) string() string { return r.p.stringAt(r.uint64()) } +func (r *importReader) name() string { return r.p.nameAt(r.uint64()) } func (r *importReader) posBase() *src.PosBase { return r.p.posBaseAt(r.uint64()) } func (r *importReader) pkg() *types.Pkg { return r.p.pkgAt(r.uint64()) } @@ -539,7 +547,7 @@ func (r *importReader) localIdent() *types.Sym { return r.ident(false) } func (r *importReader) selector() *types.Sym { return r.ident(true) } func (r *importReader) qualifiedIdent() *ir.Ident { - name := r.string() + name := r.name() pkg := r.pkg() sym := pkg.Lookup(name) return ir.NewIdent(src.NoXPos, sym) -- 2.50.0