]> Cypherpunks repositories - gostls13.git/commitdiff
gc: zero unnamed return values on entry if func has defer
authorRuss Cox <rsc@golang.org>
Mon, 12 Apr 2010 21:28:27 +0000 (14:28 -0700)
committerRuss Cox <rsc@golang.org>
Mon, 12 Apr 2010 21:28:27 +0000 (14:28 -0700)
R=ken2
CC=golang-dev
https://golang.org/cl/891050

src/cmd/gc/walk.c
test/fixedbugs/bug266.go [new file with mode: 0644]

index 34ac32436b79512d37b7e494341e99a90200deeb..5768285b84bc06e5a5d03dae49b7bf62f3685222 100644 (file)
@@ -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 (file)
index 0000000..25c246f
--- /dev/null
@@ -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)
+       }
+}