From b6c600fc9a75fd6f4b6f4478058b95902ae6be94 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 28 Feb 2017 15:51:29 -0800 Subject: [PATCH] cmd/compile/internal/gc: separate builtin and real runtime packages The builtin runtime package definitions intentionally diverge from the actual runtime package's, but this only works as long as they never overlap. To make it easier to expand the builtin runtime package, this CL now loads their definitions into a logically separate "go.runtime" package. By resetting the package's Prefix field to "runtime", any references to builtin definitions will still resolve against the real package runtime. Fixes #14482. Passes toolstash -cmp. Change-Id: I539c0994deaed4506a331f38c5b4d6bc8c95433f Reviewed-on: https://go-review.googlesource.com/37538 Run-TryBot: Matthew Dempsky TryBot-Result: Gobot Gobot Reviewed-by: Robert Griesemer --- src/cmd/compile/internal/gc/go.go | 10 +++++++++- src/cmd/compile/internal/gc/main.go | 9 +++++++-- src/cmd/compile/internal/gc/typecheck.go | 2 +- src/cmd/compile/internal/gc/walk.go | 2 +- test/runtime.go | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/cmd/compile/internal/gc/go.go b/src/cmd/compile/internal/gc/go.go index 95c1124f9e0..9bf4b493951 100644 --- a/src/cmd/compile/internal/gc/go.go +++ b/src/cmd/compile/internal/gc/go.go @@ -27,6 +27,14 @@ type Pkg struct { Syms map[string]*Sym } +// isRuntime reports whether p is package runtime. +func (p *Pkg) isRuntime() bool { + if compiling_runtime && p == localpkg { + return true + } + return p.Path == "runtime" +} + // Sym represents an object name. Most commonly, this is a Go identifier naming // an object declared within a package, but Syms are also used to name internal // synthesized objects. @@ -153,7 +161,7 @@ var itabpkg *Pkg // fake pkg for itab entries var itablinkpkg *Pkg // fake package for runtime itab entries -var Runtimepkg *Pkg // package runtime +var Runtimepkg *Pkg // fake package runtime var racepkg *Pkg // package runtime/race diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go index 2b1ae860d69..b9350d33e0a 100644 --- a/src/cmd/compile/internal/gc/main.go +++ b/src/cmd/compile/internal/gc/main.go @@ -124,9 +124,14 @@ func Main() { unsafepkg = mkpkg("unsafe") unsafepkg.Name = "unsafe" - // real package, referred to by generated runtime calls - Runtimepkg = mkpkg("runtime") + // Pseudo-package that contains the compiler's builtin + // declarations for package runtime. These are declared in a + // separate package to avoid conflicts with package runtime's + // actual declarations, which may differ intentionally but + // insignificantly. + Runtimepkg = mkpkg("go.runtime") Runtimepkg.Name = "runtime" + Runtimepkg.Prefix = "runtime" // pseudo-packages used in symbol tables itabpkg = mkpkg("go.itab") diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 1aca44bce5c..7b26b870c50 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -1289,7 +1289,7 @@ OpSwitch: if t.Results().NumFields() == 1 { n.Type = l.Type.Results().Field(0).Type - if n.Op == OCALLFUNC && n.Left.Op == ONAME && (compiling_runtime || n.Left.Sym.Pkg == Runtimepkg) && n.Left.Sym.Name == "getg" { + if n.Op == OCALLFUNC && n.Left.Op == ONAME && n.Left.Sym.Pkg.isRuntime() && n.Left.Sym.Name == "getg" { // Emit code for runtime.getg() directly instead of calling function. // Most such rewrites (for example the similar one for math.Sqrt) should be done in walk, // so that the ordering pass can make sure to preserve the semantics of the original code diff --git a/src/cmd/compile/internal/gc/walk.go b/src/cmd/compile/internal/gc/walk.go index 96f66148a53..2ba994991bd 100644 --- a/src/cmd/compile/internal/gc/walk.go +++ b/src/cmd/compile/internal/gc/walk.go @@ -1914,7 +1914,7 @@ func walkprint(nn *Node, init *Nodes) *Node { on = substArgTypes(on, n.Type) // any-1 } else if isInt[et] { if et == TUINT64 { - if (t.Sym.Pkg == Runtimepkg || compiling_runtime) && t.Sym.Name == "hex" { + if t.Sym.Pkg.isRuntime() && t.Sym.Name == "hex" { on = syslook("printhex") } else { on = syslook("printuint") diff --git a/test/runtime.go b/test/runtime.go index bccc9b53afc..0cf781b814b 100644 --- a/test/runtime.go +++ b/test/runtime.go @@ -17,5 +17,5 @@ package main import "runtime" func main() { - runtime.printbool(true) // ERROR "unexported" + runtime.printbool(true) // ERROR "unexported" "undefined" }