]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] cmd/compile: allow go'd closure to escape when compiling runtime
authorCherry Mui <cherryyz@google.com>
Thu, 3 Jun 2021 22:25:47 +0000 (18:25 -0400)
committerCherry Mui <cherryyz@google.com>
Fri, 4 Jun 2021 17:00:19 +0000 (17:00 +0000)
When compiling runtime, we don't allow closures to escape,
because we don't want (implicit) allocations to occur when it is
not okay to allocate (e.g. in the allocator itself). However, for
go statement, it already allocates a new goroutine anyway. It is
okay to allocate the closure. Allow it.

Also include the closure's name when reporting error.

Updates #40724.

Change-Id: Id7574ed17cc27709609a059c4eaa67ba1c4436dc
Reviewed-on: https://go-review.googlesource.com/c/go/+/325109
Trust: Cherry Mui <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/compile/internal/ir/expr.go
src/cmd/compile/internal/ir/func.go
src/cmd/compile/internal/walk/order.go
test/fixedbugs/issue14999.go

index 519120ed6b89c337338db0dfbbbcf6e78d231f09..856b2556575973b2252c040a8a159c283bc227fe 100644 (file)
@@ -192,6 +192,7 @@ type ClosureExpr struct {
        miniExpr
        Func     *Func `mknode:"-"`
        Prealloc *Name
+       IsGoWrap bool // whether this is wrapper closure of a go statement
 }
 
 func NewClosureExpr(pos src.XPos, fn *Func) *ClosureExpr {
index ca6c8eca8b71bdffd315d711a532808bac644cb6..1d76813a4c3898dc7c1425255db8269ccd2b90bb 100644 (file)
@@ -301,8 +301,8 @@ func ClosureDebugRuntimeCheck(clo *ClosureExpr) {
                        base.WarnfAt(clo.Pos(), "stack closure, captured vars = %v", clo.Func.ClosureVars)
                }
        }
-       if base.Flag.CompilingRuntime && clo.Esc() == EscHeap {
-               base.ErrorfAt(clo.Pos(), "heap-allocated closure, not allowed in runtime")
+       if base.Flag.CompilingRuntime && clo.Esc() == EscHeap && !clo.IsGoWrap {
+               base.ErrorfAt(clo.Pos(), "heap-allocated closure %s, not allowed in runtime", FuncName(clo.Func))
        }
 }
 
index b733d3a29f67cc18a924462a0a4c8983a8e8bf7b..19d9551566e92438aed97cc4fc44985ebbd85bf6 100644 (file)
@@ -1570,8 +1570,9 @@ func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
        // only in-register results?
        if len(callArgs) == 0 && call.Op() == ir.OCALLFUNC && callX.Type().NumResults() == 0 {
                if c, ok := call.(*ir.CallExpr); ok && callX != nil && callX.Op() == ir.OCLOSURE {
-                       cloFunc := callX.(*ir.ClosureExpr).Func
-                       cloFunc.SetClosureCalled(false)
+                       clo := callX.(*ir.ClosureExpr)
+                       clo.Func.SetClosureCalled(false)
+                       clo.IsGoWrap = true
                        c.PreserveClosure = true
                }
                return
@@ -1777,12 +1778,9 @@ func (o *orderState) wrapGoDefer(n *ir.GoDeferStmt) {
 
        // Set escape properties for closure.
        if n.Op() == ir.OGO {
-               // For "go", assume that the closure is going to escape
-               // (with an exception for the runtime, which doesn't
-               // permit heap-allocated closures).
-               if base.Ctxt.Pkgpath != "runtime" {
-                       clo.SetEsc(ir.EscHeap)
-               }
+               // For "go", assume that the closure is going to escape.
+               clo.SetEsc(ir.EscHeap)
+               clo.IsGoWrap = true
        } else {
                // For defer, just use whatever result escape analysis
                // has determined for the defer.
index b648441fc29779b1f202a20b9056da176f32e59f..a25a50e519a5ea75d90fd263ac11328b3aef09eb 100644 (file)
@@ -7,11 +7,11 @@
 package p
 
 func f(x int) func(int) int {
-       return func(y int) int { return x + y } // ERROR "heap-allocated closure, not allowed in runtime"
+       return func(y int) int { return x + y } // ERROR "heap-allocated closure f\.func1, not allowed in runtime"
 }
 
 func g(x int) func(int) int { // ERROR "x escapes to heap, not allowed in runtime"
-       return func(y int) int { // ERROR "heap-allocated closure, not allowed in runtime"
+       return func(y int) int { // ERROR "heap-allocated closure g\.func1, not allowed in runtime"
                x += y
                return x + y
        }