cmd/5g, cmd/6g, cmd/8g: flush return parameters in case of panic.

Fixes #4066.

R=rsc, minux.ma
CC=golang-dev
https://golang.org/cl/7040044
This commit is contained in:
Daniel Morsing 2013-01-04 17:07:21 +01:00
parent 62dfa9c47d
commit f1e4ee3f49
4 changed files with 52 additions and 3 deletions

View file

@ -1075,8 +1075,12 @@ prop(Reg *r, Bits ref, Bits cal)
default:
// Work around for issue 1304:
// flush modified globals before each instruction.
for(z=0; z<BITS; z++)
for(z=0; z<BITS; z++) {
cal.b[z] |= externs.b[z];
// issue 4066: flush modified return variables in case of panic
if(hasdefer)
cal.b[z] |= ovar.b[z];
}
break;
}
for(z=0; z<BITS; z++) {

View file

@ -1121,8 +1121,12 @@ prop(Reg *r, Bits ref, Bits cal)
default:
// Work around for issue 1304:
// flush modified globals before each instruction.
for(z=0; z<BITS; z++)
for(z=0; z<BITS; z++) {
cal.b[z] |= externs.b[z];
// issue 4066: flush modified return variables in case of panic
if(hasdefer)
cal.b[z] |= ovar.b[z];
}
break;
}
for(z=0; z<BITS; z++) {

View file

@ -1048,8 +1048,12 @@ prop(Reg *r, Bits ref, Bits cal)
default:
// Work around for issue 1304:
// flush modified globals before each instruction.
for(z=0; z<BITS; z++)
for(z=0; z<BITS; z++) {
cal.b[z] |= externs.b[z];
// issue 4066: flush modified return variables in case of panic
if(hasdefer)
cal.b[z] |= ovar.b[z];
}
break;
}
for(z=0; z<BITS; z++) {

View file

@ -0,0 +1,37 @@
// run
// Copyright 2012 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.
// issue 4066: return values not being spilled eagerly enough
package main
func main() {
n := foo()
if n != 2 {
println(n)
panic("wrong return value")
}
}
type terr struct{}
func foo() (val int) {
val = 0
defer func() {
if x := recover(); x != nil {
_ = x.(terr)
}
}()
for {
val = 2
foo1()
}
panic("unreachable")
}
func foo1() {
panic(terr{})
}