The gccgo implementation of panic/recover uses the return address of a function which called recover in order to see if that function was invoke directly by defer. It does this by passing the address of a label which immediately follows the function call. This requires a small heuristic, because there may be some machine instructions between the function call and the label, even though they are adjacent in GIMPLE. On SPARC I needed to tweak that heuristic further, because on SPARC __builtin_return_address returns the address of the function call instruction, which is at least 8 bytes before the label. This patch implements that tweak. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu and sparc-sun-solaris2.11 (Solaris has other unrelated failures). Committed to mainline.
Ian
Index: libgo/runtime/go-recover.c =================================================================== --- libgo/runtime/go-recover.c (revision 183650) +++ libgo/runtime/go-recover.c (working copy) @@ -43,6 +43,14 @@ __go_can_recover (const void* retaddr) such as an instruction to adjust the stack pointer. */ ret = (const char *) retaddr; + +#ifdef __sparc__ + /* On SPARC the address we get, from __builtin_return_address, is + the address of the call instruction. Adjust forward, also + skipping the delayed instruction following the call. */ + ret += 8; +#endif + dret = (const char *) d->__retaddr; return ret <= dret && ret + 16 >= dret; }