From: Cuong Manh Le Date: Mon, 27 Jul 2020 05:08:56 +0000 (+0700) Subject: cmd/compile: handle OCLOSURE/OCALLPART in mustHeapAlloc check X-Git-Tag: go1.16beta1~1354 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=82c45eb68187d7827bca392d528dbfa06607e3f0;p=gostls13.git cmd/compile: handle OCLOSURE/OCALLPART in mustHeapAlloc check 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 TryBot-Result: Gobot Gobot Reviewed-by: Matthew Dempsky --- diff --git a/src/cmd/compile/internal/gc/closure.go b/src/cmd/compile/internal/gc/closure.go index 3bb7bb9834..04fb7d5495 100644 --- a/src/cmd/compile/internal/gc/closure.go +++ b/src/cmd/compile/internal/gc/closure.go @@ -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. diff --git a/src/cmd/compile/internal/gc/esc.go b/src/cmd/compile/internal/gc/esc.go index f3e9ab78ef..628953741a 100644 --- a/src/cmd/compile/internal/gc/esc.go +++ b/src/cmd/compile/internal/gc/esc.go @@ -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 index 0000000000..5d6595c234 --- /dev/null +++ b/test/fixedbugs/issue39292.go @@ -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() +}