diff options
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | libgo/go/runtime/panic.go | 17 |
2 files changed, 14 insertions, 5 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index dbba68f..df38903 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -7a941ba323660ec7034cd92d4eab466024a3c72c +2442fca7be8a4f51ddc91070fa69ef66e24593ac The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go index 0ad178f..f7e5efe 100644 --- a/libgo/go/runtime/panic.go +++ b/libgo/go/runtime/panic.go @@ -415,10 +415,19 @@ func gopanic(e interface{}) { throw("panic holding locks") } - var p _panic - p.arg = e - p.link = gp._panic - gp._panic = (*_panic)(noescape(unsafe.Pointer(&p))) + // The gc compiler allocates this new _panic struct on the + // stack. We can't do that, because when a deferred function + // recovers the panic we unwind the stack. We unlink this + // entry before unwinding the stack, but that doesn't help in + // the case where we panic, a deferred function recovers and + // then panics itself, that panic is in turn recovered, and + // unwinds the stack past this stack frame. + + p := &_panic{ + arg: e, + link: gp._panic, + } + gp._panic = p for { d := gp._defer |