diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2022-04-29 10:47:57 -0700 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2022-04-29 18:35:07 +0000 |
| commit | 8c5917cd76905b1ab16d41eadc8786e190eeecce (patch) | |
| tree | 976eab01e6911428e99ca13ca97e8a5b202c3af5 /src | |
| parent | e7c56fe9948449a3710b36c22c02d57c215d1c10 (diff) | |
| download | go-8c5917cd76905b1ab16d41eadc8786e190eeecce.tar.xz | |
cmd/compile: consistent unified IR handling of package unsafe
Within the unified IR export format, I was treating package unsafe as
a normal package, but expecting importers to correctly handle
deduplicating it against their respective representation of package
unsafe.
However, the surrounding importer logic differs slightly between
cmd/compile/internal/noder (which unified IR was originally
implemented against) and go/importer (which it was more recently
ported to). In particular, noder initializes its packages map as
`map[string]*types2.Package{"unsafe": types2.Unsafe}`, whereas
go/importer initializes it as just `make(map[string]*types.Package)`.
This CL makes them all consistent. In particular, it:
1. changes noder to initialize packages to an empty map to prevent
further latent issues from the discrepency,
2. adds the same special handling of package unsafe already present in
go/internal/gcimporter's unified IR reader to both of cmd/compile's
implementations, and
3. changes the unified IR writer to treat package unsafe as a builtin
package, to force that readers similarly handle it correctly.
Fixes #52623.
Change-Id: Ibbab9b0a1d2a52d4cc91b56c5df49deedf81295a
Reviewed-on: https://go-review.googlesource.com/c/go/+/403196
Auto-Submit: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/compile/internal/importer/ureader.go | 12 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/irgen.go | 2 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 10 | ||||
| -rw-r--r-- | src/cmd/compile/internal/noder/writer.go | 14 | ||||
| -rw-r--r-- | src/go/internal/gcimporter/ureader.go | 11 |
5 files changed, 30 insertions, 19 deletions
diff --git a/src/cmd/compile/internal/importer/ureader.go b/src/cmd/compile/internal/importer/ureader.go index a22cd2bb53..b8938cd2d6 100644 --- a/src/cmd/compile/internal/importer/ureader.go +++ b/src/cmd/compile/internal/importer/ureader.go @@ -148,11 +148,13 @@ func (pr *pkgReader) pkgIdx(idx int) *types2.Package { func (r *reader) doPkg() *types2.Package { path := r.String() - if path == "builtin" { - return nil // universe - } - if path == "" { + switch path { + case "": path = r.p.PkgPath() + case "builtin": + return nil // universe + case "unsafe": + return types2.Unsafe } if pkg := r.p.imports[path]; pkg != nil { @@ -371,7 +373,7 @@ func (pr *pkgReader) objIdx(idx int) (*types2.Package, string) { tag := pkgbits.CodeObj(rname.Code(pkgbits.SyncCodeObj)) if tag == pkgbits.ObjStub { - assert(objPkg == nil || objPkg == types2.Unsafe) + base.Assertf(objPkg == nil || objPkg == types2.Unsafe, "unexpected stub package: %v", objPkg) return objPkg, objName } diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go index 5499ccd405..628c0f54fc 100644 --- a/src/cmd/compile/internal/noder/irgen.go +++ b/src/cmd/compile/internal/noder/irgen.go @@ -36,7 +36,7 @@ func checkFiles(noders []*noder) (posMap, *types2.Package, *types2.Info) { ctxt := types2.NewContext() importer := gcimports{ ctxt: ctxt, - packages: map[string]*types2.Package{"unsafe": types2.Unsafe}, + packages: make(map[string]*types2.Package), } conf := types2.Config{ Context: ctxt, diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 1350c22467..83ebe24779 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -282,11 +282,13 @@ func (pr *pkgReader) pkgIdx(idx int) *types.Pkg { func (r *reader) doPkg() *types.Pkg { path := r.String() - if path == "builtin" { - return types.BuiltinPkg - } - if path == "" { + switch path { + case "": path = r.p.PkgPath() + case "builtin": + return types.BuiltinPkg + case "unsafe": + return types.UnsafePkg } name := r.String() diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go index 0fb162d381..39f0ad794f 100644 --- a/src/cmd/compile/internal/noder/writer.go +++ b/src/cmd/compile/internal/noder/writer.go @@ -214,13 +214,21 @@ func (pw *pkgWriter) pkgIdx(pkg *types2.Package) int { w := pw.newWriter(pkgbits.RelocPkg, pkgbits.SyncPkgDef) pw.pkgsIdx[pkg] = w.Idx - if pkg == nil { - w.String("builtin") - } else { + // The universe and package unsafe need to be handled specially by + // importers anyway, so we serialize them using just their package + // path. This ensures that readers don't confuse them for + // user-defined packages. + switch pkg { + case nil: // universe + w.String("builtin") // same package path used by godoc + case types2.Unsafe: + w.String("unsafe") + default: var path string if pkg != w.p.curpkg { path = pkg.Path() } + base.Assertf(path != "builtin" && path != "unsafe", "unexpected path for user-defined package: %q", path) w.String(path) w.String(pkg.Name()) w.Len(pkg.Height()) diff --git a/src/go/internal/gcimporter/ureader.go b/src/go/internal/gcimporter/ureader.go index 5260759c4f..e27d3e0b4d 100644 --- a/src/go/internal/gcimporter/ureader.go +++ b/src/go/internal/gcimporter/ureader.go @@ -184,15 +184,14 @@ func (pr *pkgReader) pkgIdx(idx int) *types.Package { func (r *reader) doPkg() *types.Package { path := r.String() - if path == "builtin" { + switch path { + case "": + path = r.p.PkgPath() + case "builtin": return nil // universe - } - if path == "unsafe" { + case "unsafe": return types.Unsafe } - if path == "" { - path = r.p.PkgPath() - } if pkg := r.p.imports[path]; pkg != nil { return pkg |
