]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/compile: keep all open-coded defer slots as used
authorMatthew Dempsky <mdempsky@google.com>
Wed, 9 Aug 2023 16:04:37 +0000 (09:04 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 9 Aug 2023 16:43:33 +0000 (16:43 +0000)
Open-coded defer slots are assigned indices upfront, so they're
logically like elements in an array. Without reassigning the indices,
we need to keep all of the elements alive so their relative offsets
are correct.

Fixes #61895.

Change-Id: Ie0191fdb33276f4e8ed0becb69086524fff022b2
Reviewed-on: https://go-review.googlesource.com/c/go/+/517856
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/ssagen/pgen.go
test/fixedbugs/issue61895.go [new file with mode: 0644]

index ca064a16a7d920e185f82acfaf1aa904381d431f..e7a0699641bf8ddfce8487e4f4ee9ec0ac6fc445 100644 (file)
@@ -121,6 +121,14 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
 
        // Mark the PAUTO's unused.
        for _, ln := range fn.Dcl {
+               if ln.OpenDeferSlot() {
+                       // Open-coded defer slots have indices that were assigned
+                       // upfront during SSA construction, but the defer statement can
+                       // later get removed during deadcode elimination (#61895). To
+                       // keep their relative offsets correct, treat them all as used.
+                       continue
+               }
+
                if needAlloc(ln) {
                        ln.SetUsed(false)
                }
diff --git a/test/fixedbugs/issue61895.go b/test/fixedbugs/issue61895.go
new file mode 100644 (file)
index 0000000..cda6494
--- /dev/null
@@ -0,0 +1,15 @@
+// compile
+
+// Copyright 2023 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 main
+
+func main() {
+       for {
+       }
+
+       defer func() {}()
+       defer func() {}()
+}