aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-04-12 14:28:27 -0700
committerRuss Cox <rsc@golang.org>2010-04-12 14:28:27 -0700
commitd9254d00f9fdb3499bee4347e7eb3de53f673bc6 (patch)
treed71e5c8087e883229e1254c1eaf517872b0e9faa
parent9149d91888fc9aa05bb44af6b67508cc16861db5 (diff)
downloadgo-d9254d00f9fdb3499bee4347e7eb3de53f673bc6.tar.gz
go-d9254d00f9fdb3499bee4347e7eb3de53f673bc6.zip
gc: zero unnamed return values on entry if func has defer
R=ken2 CC=golang-dev https://golang.org/cl/891050
-rw-r--r--src/cmd/gc/walk.c14
-rw-r--r--test/fixedbugs/bug266.go26
2 files changed, 36 insertions, 4 deletions
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 34ac32436b..5768285b84 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -2312,7 +2312,7 @@ reorder4(NodeList *ll)
* copies of escaped parameters to the heap.
*/
NodeList*
-paramstoheap(Type **argin)
+paramstoheap(Type **argin, int out)
{
Type *t;
Iter savet;
@@ -2322,6 +2322,12 @@ paramstoheap(Type **argin)
nn = nil;
for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
v = t->nname;
+ if(v == N && out && hasdefer) {
+ // Defer might stop a panic and show the
+ // return values as they exist at the time of panic.
+ // Make sure to zero them on entry to the function.
+ nn = list(nn, nod(OAS, nodarg(t, 1), N));
+ }
if(v == N || !(v->class & PHEAP))
continue;
@@ -2366,9 +2372,9 @@ heapmoves(void)
{
NodeList *nn;
- nn = paramstoheap(getthis(curfn->type));
- nn = concat(nn, paramstoheap(getinarg(curfn->type)));
- nn = concat(nn, paramstoheap(getoutarg(curfn->type)));
+ nn = paramstoheap(getthis(curfn->type), 0);
+ nn = concat(nn, paramstoheap(getinarg(curfn->type), 0));
+ nn = concat(nn, paramstoheap(getoutarg(curfn->type), 1));
curfn->enter = concat(curfn->enter, nn);
curfn->exit = returnsfromheap(getoutarg(curfn->type));
}
diff --git a/test/fixedbugs/bug266.go b/test/fixedbugs/bug266.go
new file mode 100644
index 0000000000..25c246f7df
--- /dev/null
+++ b/test/fixedbugs/bug266.go
@@ -0,0 +1,26 @@
+// $G $D/$F.go && $L $F.$A && ./$A.out || echo BUG: bug266
+
+// Copyright 2010 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 f() int {
+ defer func() {
+ recover()
+ }()
+ panic("oops")
+}
+
+func g() int {
+ return 12345
+}
+
+func main() {
+ g() // leave 12345 on stack
+ x := f()
+ if x != 0 {
+ panic(x)
+ }
+}