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/irgen.go7
-rw-r--r--src/cmd/compile/internal/noder/reader.go12
-rw-r--r--src/cmd/compile/internal/noder/unified.go4
-rw-r--r--src/cmd/compile/internal/noder/writer.go17
4 files changed, 24 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/noder/irgen.go b/src/cmd/compile/internal/noder/irgen.go
index 4d51c6b446..a95fa03e17 100644
--- a/src/cmd/compile/internal/noder/irgen.go
+++ b/src/cmd/compile/internal/noder/irgen.go
@@ -22,7 +22,8 @@ var versionErrorRx = regexp.MustCompile(`requires go[0-9]+\.[0-9]+ or later`)
// checkFiles configures and runs the types2 checker on the given
// parsed source files and then returns the result.
-func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) {
+// The map result value indicates which closures are generated from the bodies of range function loops.
+func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info, map[*syntax.FuncLit]bool) {
if base.SyntaxErrors() != 0 {
base.ErrorExit()
}
@@ -150,9 +151,9 @@ func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info) {
// If we do the rewrite in the back end, like between typecheck and walk,
// then the new implicit closure will not have a unified IR inline body,
// and bodyReaderFor will fail.
- rangefunc.Rewrite(pkg, info, files)
+ rangeInfo := rangefunc.Rewrite(pkg, info, files)
- return pkg, info
+ return pkg, info, rangeInfo
}
// A cycleFinder detects anonymous interface cycles (go.dev/issue/56103).
diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go
index a7feadaf6e..042d81bbcd 100644
--- a/src/cmd/compile/internal/noder/reader.go
+++ b/src/cmd/compile/internal/noder/reader.go
@@ -2704,7 +2704,7 @@ func (r *reader) syntheticClosure(origPos src.XPos, typ *types.Type, ifaceHack b
return false
}
- fn := r.inlClosureFunc(origPos, typ)
+ fn := r.inlClosureFunc(origPos, typ, ir.OCLOSURE)
fn.SetWrapper(true)
clo := fn.OClosure
@@ -3035,8 +3035,12 @@ func (r *reader) funcLit() ir.Node {
origPos := r.pos()
sig := r.signature(nil)
r.suppressInlPos--
+ why := ir.OCLOSURE
+ if r.Bool() {
+ why = ir.ORANGE
+ }
- fn := r.inlClosureFunc(origPos, sig)
+ fn := r.inlClosureFunc(origPos, sig, why)
fn.ClosureVars = make([]*ir.Name, 0, r.Len())
for len(fn.ClosureVars) < cap(fn.ClosureVars) {
@@ -3062,14 +3066,14 @@ func (r *reader) funcLit() ir.Node {
// inlClosureFunc constructs a new closure function, but correctly
// handles inlining.
-func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type) *ir.Func {
+func (r *reader) inlClosureFunc(origPos src.XPos, sig *types.Type, why ir.Op) *ir.Func {
curfn := r.inlCaller
if curfn == nil {
curfn = r.curfn
}
// TODO(mdempsky): Remove hard-coding of typecheck.Target.
- return ir.NewClosureFunc(origPos, r.inlPos(origPos), ir.OCLOSURE, sig, curfn, typecheck.Target)
+ return ir.NewClosureFunc(origPos, r.inlPos(origPos), why, sig, curfn, typecheck.Target)
}
func (r *reader) exprList() []ir.Node {
diff --git a/src/cmd/compile/internal/noder/unified.go b/src/cmd/compile/internal/noder/unified.go
index 2391b2f34d..a1a90cd6b5 100644
--- a/src/cmd/compile/internal/noder/unified.go
+++ b/src/cmd/compile/internal/noder/unified.go
@@ -304,9 +304,9 @@ func readBodies(target *ir.Package, duringInlining bool) {
// writes an export data package stub representing them,
// and returns the result.
func writePkgStub(m posMap, noders []*noder) string {
- pkg, info := checkFiles(m, noders)
+ pkg, info, otherInfo := checkFiles(m, noders)
- pw := newPkgWriter(m, pkg, info)
+ pw := newPkgWriter(m, pkg, info, otherInfo)
pw.collectDecls(noders)
diff --git a/src/cmd/compile/internal/noder/writer.go b/src/cmd/compile/internal/noder/writer.go
index 13706f9dd2..9b33fb7c6d 100644
--- a/src/cmd/compile/internal/noder/writer.go
+++ b/src/cmd/compile/internal/noder/writer.go
@@ -63,9 +63,10 @@ import (
type pkgWriter struct {
pkgbits.PkgEncoder
- m posMap
- curpkg *types2.Package
- info *types2.Info
+ m posMap
+ curpkg *types2.Package
+ info *types2.Info
+ rangeFuncBodyClosures map[*syntax.FuncLit]bool // non-public information, e.g., which functions are closures range function bodies?
// Indices for previously written syntax and types2 things.
@@ -90,13 +91,14 @@ type pkgWriter struct {
// newPkgWriter returns an initialized pkgWriter for the specified
// package.
-func newPkgWriter(m posMap, pkg *types2.Package, info *types2.Info) *pkgWriter {
+func newPkgWriter(m posMap, pkg *types2.Package, info *types2.Info, otherInfo map[*syntax.FuncLit]bool) *pkgWriter {
return &pkgWriter{
PkgEncoder: pkgbits.NewPkgEncoder(base.Debug.SyncFrames),
- m: m,
- curpkg: pkg,
- info: info,
+ m: m,
+ curpkg: pkg,
+ info: info,
+ rangeFuncBodyClosures: otherInfo,
pkgsIdx: make(map[*types2.Package]pkgbits.Index),
objsIdx: make(map[types2.Object]pkgbits.Index),
@@ -2336,6 +2338,7 @@ func (w *writer) funcLit(expr *syntax.FuncLit) {
w.Sync(pkgbits.SyncFuncLit)
w.pos(expr)
w.signature(sig)
+ w.Bool(w.p.rangeFuncBodyClosures[expr])
w.Len(len(closureVars))
for _, cv := range closureVars {