]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: handle OCLOSURE/OCALLPART in mustHeapAlloc check
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Mon, 27 Jul 2020 05:08:56 +0000 (12:08 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Sat, 15 Aug 2020 03:09:35 +0000 (03:09 +0000)
Currently, generated struct wrapper for closure is not handled in
mustHeapAlloc. That causes compiler crashes when the wrapper struct
is too large for stack, and must be heap allocated instead.

Fixes #39292

Change-Id: I14c1e591681d9d92317bb2396d6cf5207aa93e08
Reviewed-on: https://go-review.googlesource.com/c/go/+/244917
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/gc/closure.go
src/cmd/compile/internal/gc/esc.go
test/fixedbugs/issue39292.go [new file with mode: 0644]

index 3bb7bb98345f2a7ce4bf775aeb06fe79b080dca4..04fb7d54951d20bd2571a80ed32a3eefb596e2ef 100644 (file)
@@ -526,7 +526,7 @@ func walkpartialcall(n *Node, init *Nodes) *Node {
        // Create closure in the form of a composite literal.
        // For x.M with receiver (x) type T, the generated code looks like:
        //
-       //      clos = &struct{F uintptr; R T}{M.T·f, x}
+       //      clos = &struct{F uintptr; R T}{T.M·f, x}
        //
        // Like walkclosure above.
 
index f3e9ab78ef06814a28e00a6d93ebab7de2413d55..628953741a352ed2d953eb09de81702575346e42 100644 (file)
@@ -187,6 +187,13 @@ func mustHeapAlloc(n *Node) bool {
                return true
        }
 
+       if n.Op == OCLOSURE && closureType(n).Size() >= maxImplicitStackVarSize {
+               return true
+       }
+       if n.Op == OCALLPART && partialCallType(n).Size() >= maxImplicitStackVarSize {
+               return true
+       }
+
        if n.Op == OMAKESLICE && !isSmallMakeSlice(n) {
                return true
        }
diff --git a/test/fixedbugs/issue39292.go b/test/fixedbugs/issue39292.go
new file mode 100644 (file)
index 0000000..5d6595c
--- /dev/null
@@ -0,0 +1,29 @@
+// errorcheck -0 -m -l
+
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package p
+
+type t [10000]*int
+
+func (t) f() {
+}
+
+func x() {
+       x := t{}.f // ERROR "t literal.f escapes to heap"
+       x()
+}
+
+func y() {
+       var i int       // ERROR "moved to heap: i"
+       y := (&t{&i}).f // ERROR "\(&t literal\).f escapes to heap" "&t literal escapes to heap"
+       y()
+}
+
+func z() {
+       var i int    // ERROR "moved to heap: i"
+       z := t{&i}.f // ERROR "t literal.f escapes to heap"
+       z()
+}