]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/5g, cmd/6g, cmd/8g: flush return parameters in case of panic.
authorDaniel Morsing <daniel.morsing@gmail.com>
Fri, 4 Jan 2013 16:07:21 +0000 (17:07 +0100)
committerDaniel Morsing <daniel.morsing@gmail.com>
Fri, 4 Jan 2013 16:07:21 +0000 (17:07 +0100)
Fixes #4066.

R=rsc, minux.ma
CC=golang-dev
https://golang.org/cl/7040044

src/cmd/5g/reg.c
src/cmd/6g/reg.c
src/cmd/8g/reg.c
test/fixedbugs/issue4066.go [new file with mode: 0644]

index 5f7ed2e88dfc3812fb9473e1174d1c8df8a0b081..584ffc253478d361646987dd6d27aff20f01dd8c 100644 (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++) {
index 8d15bf979033e038d070e1a12589d77917764e98..9c9b74d0ed1391ace728b356855fad195086e5bb 100644 (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++) {
index 80230bc866877050e556f5f4737a50a82d36b3d2..7b8b39e8bcc91bba5141b14b0a5b93571ad9634f 100644 (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++) {
diff --git a/test/fixedbugs/issue4066.go b/test/fixedbugs/issue4066.go
new file mode 100644 (file)
index 0000000..19cfe66
--- /dev/null
@@ -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{})
+}