https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60406

--- Comment #18 from Ian Lance Taylor <ian at airs dot com> ---
> Well, maybe it was only a problem with tail recursion, ....

Note that because Go programs expect predictable results from runtime.Callers
and other stack backtracing functions, the Go frontend disables tail recursion
(go_langhook_post_options in gcc/go/go-lang.c).


> Hm, so the patch penalises platforms that cannot deal with the 16 byte window?

Yes, but, recall that on your system almost all tests pass using the code that
is in the tree today, before your patch.  The only tests that fail are the very
challenging ones in recover.go, that stress test the panic/recover mechanism
but are in no way representative of real code.  The normal tests all works
fine.  So while there is a penalty, it is one that only occurs in rare cases.


>>>   func main() { defer foo(); panic("..."); }
>>>   func foo() { defer bar(); }
>>>   func bar() { recover(); }
>>
>> In this case, the call to recover in bar is supposed to return nil;
>> it should not recover the panic.  If you read the paragraph before
>> the one you quote, you will see that recover only returns non-nil
>> if it was called by a function that was deferred before the call to
>> panic.
>
>I've read it but cannot see anything that would disallow recovery in this
> situation.  What exactly do you mean?

The spec says "Suppose a function G defers a function D that calls recover and
a panic occurs in a function on the same goroutine in which G is executing." 
The order is 1) G defers D; 2) a panic occurs.  In your example above, this
applies to main defers foo and then a panic occurs.  It does not apply to foo
defers bar, because there is no panic after foo defers bar (the panic has
already occurred--that is why we are executing foo).  Since there is no panic,
the recover in bar returns nil.

The recover.go file tests this pattern in, e.g., test1WithClosures.

Reply via email to