1
0
mirror of https://github.com/golang/go synced 2024-11-25 11:57:58 -07:00

gc: zero unnamed return values on entry if func has defer

R=ken2
CC=golang-dev
https://golang.org/cl/891050
This commit is contained in:
Russ Cox 2010-04-12 14:28:27 -07:00
parent 9149d91888
commit d9254d00f9
2 changed files with 36 additions and 4 deletions

View File

@ -2312,7 +2312,7 @@ reorder4(NodeList *ll)
* copies of escaped parameters to the heap. * copies of escaped parameters to the heap.
*/ */
NodeList* NodeList*
paramstoheap(Type **argin) paramstoheap(Type **argin, int out)
{ {
Type *t; Type *t;
Iter savet; Iter savet;
@ -2322,6 +2322,12 @@ paramstoheap(Type **argin)
nn = nil; nn = nil;
for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) { for(t = structfirst(&savet, argin); t != T; t = structnext(&savet)) {
v = t->nname; 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)) if(v == N || !(v->class & PHEAP))
continue; continue;
@ -2366,9 +2372,9 @@ heapmoves(void)
{ {
NodeList *nn; NodeList *nn;
nn = paramstoheap(getthis(curfn->type)); nn = paramstoheap(getthis(curfn->type), 0);
nn = concat(nn, paramstoheap(getinarg(curfn->type))); nn = concat(nn, paramstoheap(getinarg(curfn->type), 0));
nn = concat(nn, paramstoheap(getoutarg(curfn->type))); nn = concat(nn, paramstoheap(getoutarg(curfn->type), 1));
curfn->enter = concat(curfn->enter, nn); curfn->enter = concat(curfn->enter, nn);
curfn->exit = returnsfromheap(getoutarg(curfn->type)); curfn->exit = returnsfromheap(getoutarg(curfn->type));
} }

26
test/fixedbugs/bug266.go Normal file
View File

@ -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)
}
}