aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/noder
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/noder')
-rw-r--r--src/cmd/compile/internal/noder/reader.go77
-rw-r--r--src/cmd/compile/internal/noder/writer.go9
2 files changed, 41 insertions, 45 deletions
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index 0efe2ea2d5..01f001f199 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -2988,52 +2988,12 @@ func (r *reader) multiExpr() []ir.Node {
// temp returns a new autotemp of the specified type.
func (r *reader) temp(pos src.XPos, typ *types.Type) *ir.Name {
- // See typecheck.typecheckargs.
- curfn := r.curfn
- if curfn == nil {
- curfn = typecheck.InitTodoFunc
- }
-
- return typecheck.TempAt(pos, curfn, typ)
+ return typecheck.TempAt(pos, r.curfn, typ)
}
// tempCopy declares and returns a new autotemp initialized to the
// value of expr.
func (r *reader) tempCopy(pos src.XPos, expr ir.Node, init *ir.Nodes) *ir.Name {
- if r.curfn == nil {
- // Escape analysis doesn't know how to handle package-scope
- // function literals with free variables (i.e., that capture
- // temporary variables added to typecheck.InitTodoFunc).
- //
- // stencil.go works around this limitation by spilling values to
- // global variables instead, but that causes the value to stay
- // alive indefinitely; see go.dev/issue/54343.
- //
- // This code path (which implements the same workaround) isn't
- // actually needed by unified IR, because it creates uses normal
- // OMETHEXPR/OMETHVALUE nodes when statically-known instantiated
- // types are used. But it's kept around for now because it's handy
- // for testing that the generic fallback paths work correctly.
- base.Fatalf("tempCopy called at package scope")
-
- tmp := staticinit.StaticName(expr.Type())
-
- assign := ir.NewAssignStmt(pos, tmp, expr)
- assign.Def = true
- tmp.Defn = assign
-
- // TODO(mdempsky): This code doesn't work anymore, because we now
- // rely on types2 to compute InitOrder. If it's going to be used
- // for testing again, the assignment here probably needs to be
- // added to typecheck.Target.InitOrder somewhere.
- //
- // Probably just easier to address the escape analysis limitation.
- //
- // typecheck.Target.Decls = append(typecheck.Target.Decls, typecheck.Stmt(assign))
-
- return tmp
- }
-
tmp := r.temp(pos, expr.Type())
init.Append(typecheck.Stmt(ir.NewDecl(pos, ir.ODCL, tmp)))
@@ -3328,9 +3288,32 @@ func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) {
}
target.CgoPragmas = cgoPragmas
+ r.pkgInitOrder(target)
+
r.pkgDecls(target)
+ r.Sync(pkgbits.SyncEOF)
+}
+
+// pkgInitOrder creates a synthetic init function to handle any
+// package-scope initialization statements.
+func (r *reader) pkgInitOrder(target *ir.Package) {
initOrder := make([]ir.Node, r.Len())
+ if len(initOrder) == 0 {
+ return
+ }
+
+ // Make a function that contains all the initialization statements.
+ pos := base.AutogeneratedPos
+ base.Pos = pos
+
+ fn := ir.NewFunc(pos, pos, typecheck.Lookup("init"), types.NewSignature(nil, nil, nil))
+ fn.SetIsPackageInit(true)
+ fn.SetInlinabilityChecked(true) // suppress useless "can inline" diagnostics
+
+ typecheck.DeclFunc(fn)
+ r.curfn = fn
+
for i := range initOrder {
lhs := make([]ir.Node, r.Len())
for j := range lhs {
@@ -3352,9 +3335,17 @@ func (r *reader) pkgInit(self *types.Pkg, target *ir.Package) {
initOrder[i] = as
}
- target.InitOrder = initOrder
- r.Sync(pkgbits.SyncEOF)
+ fn.Body = initOrder
+
+ typecheck.FinishFuncBody()
+ r.curfn = nil
+ r.locals = nil
+
+ // Outline (if legal/profitable) global map inits.
+ staticinit.OutlineMapInits(fn)
+
+ target.Inits = append(target.Inits, fn)
}
func (r *reader) pkgDecls(target *ir.Package) {
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go
index 10cf46f3f2..5982e714a3 100644
--- a/src/cmd/compile/internal/noder/writer.go
+++ b/src/cmd/compile/internal/noder/writer.go
@@ -2597,6 +2597,8 @@ func (w *writer) pkgInit(noders []*noder) {
w.Strings(cgoPragma)
}
+ w.pkgInitOrder()
+
w.Sync(pkgbits.SyncDecls)
for _, p := range noders {
for _, decl := range p.file.DeclList {
@@ -2605,6 +2607,11 @@ func (w *writer) pkgInit(noders []*noder) {
}
w.Code(declEnd)
+ w.Sync(pkgbits.SyncEOF)
+}
+
+func (w *writer) pkgInitOrder() {
+ // TODO(mdempsky): Write as a function body instead?
w.Len(len(w.p.info.InitOrder))
for _, init := range w.p.info.InitOrder {
w.Len(len(init.Lhs))
@@ -2613,8 +2620,6 @@ func (w *writer) pkgInit(noders []*noder) {
}
w.expr(init.Rhs)
}
-
- w.Sync(pkgbits.SyncEOF)
}
func (w *writer) pkgDecl(decl syntax.Decl) {