aboutsummaryrefslogtreecommitdiff
path: root/test/abi
diff options
context:
space:
mode:
authorCherry Zhang <cherryyz@google.com>2021-04-03 20:09:15 -0400
committerCherry Zhang <cherryyz@google.com>2021-04-06 20:22:15 +0000
commitf5efa5a313cbfdbd86aa342f8bc2a4cc66f51a6e (patch)
treecdbe97e33471553618e9ef442bbdd134827b8945 /test/abi
parentbcc4422ee1bdb8051a6c870cf00e837814614a0f (diff)
downloadgo-f5efa5a313cbfdbd86aa342f8bc2a4cc66f51a6e.tar.gz
go-f5efa5a313cbfdbd86aa342f8bc2a4cc66f51a6e.zip
cmd/compile: load results into registers on open defer return path
When a function panics then recovers, it needs to return to the caller with named results having the correct values. For in-register results, we need to load them into registers at the defer return path. For non-open-coded defers, we already generate correct code, as the defer return path is part of the SSA CFG and contains the instructions that are the same as an ordinary return statement, including putting the results to the right places. For open-coded defers, we have a special code generation that emits a disconnected block that currently contains only the deferreturn call and a RET instruction. It leaves the result registers unset. This CL adds instructions that load the result registers on that path. Updates #40724. Change-Id: I1f60514da644fd5fb4b4871a1153c62f42927282 Reviewed-on: https://go-review.googlesource.com/c/go/+/307231 Trust: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Austin Clements <austin@google.com>
Diffstat (limited to 'test/abi')
-rw-r--r--test/abi/defer_recover_results.go36
1 files changed, 36 insertions, 0 deletions
diff --git a/test/abi/defer_recover_results.go b/test/abi/defer_recover_results.go
new file mode 100644
index 0000000000..7787f26f4c
--- /dev/null
+++ b/test/abi/defer_recover_results.go
@@ -0,0 +1,36 @@
+// run
+
+// Copyright 2021 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.
+
+// Test that when a function recovers from a panic, it
+// returns the correct results to the caller (in particular,
+// setting the result registers correctly).
+
+package main
+
+type S struct {
+ x uint8
+ y uint16
+ z uint32
+ w float64
+}
+
+var a0, b0, c0, d0 = 10, "hello", S{1, 2, 3, 4}, [2]int{111, 222}
+
+//go:noinline
+//go:registerparams
+func F() (a int, b string, _ int, c S, d [2]int) {
+ a, b, c, d = a0, b0, c0, d0
+ defer func() { recover() }()
+ panic("XXX")
+ return
+}
+
+func main() {
+ a1, b1, zero, c1, d1 := F()
+ if a1 != a0 || b1 != b0 || c1 != c0 || d1 != d0 || zero != 0 { // unnamed result gets zero value
+ panic("FAIL")
+ }
+}