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>
// 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.
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
}
--- /dev/null
+// 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()
+}