Sandra Loosemore <[email protected]> writes:
> I have written a new patch for PR 59039 to address more of the comments
> there, as well as my own complaints about the draft patch attached to
> the issue. I'd like to get some feedback on this one before I commit it.
It's a long time since I've worked with these builtins and I'd need
to look at the code to remember how they work. Reading this without
doing that...
> +@node Nonlocal Gotos
> +@section Nonlocal Gotos
> +@cindex nonlocal gotos
This could be confusing, since GCC supports a "true" form of non-local
goto from nested functions to containing functions, using the "goto"
keyword.
> +GCC provides the built-in functions @code{__builtin_setjmp} and
> +@code{__builtin_longjmp} which are similar to, but not interchangeable
> +with, the C library functions @code{setjmp} and @code{longjmp}.
> +The built-in versions are used internally by GCC's libraries
> +to implement exception handling on some targets. You should use the
> +standard C library functions declared in @code{<setjmp.h>} in user code
> +instead of the builtins.
> +
> +@code{__builtin_setjmp} and @code{__builtin_longjmp} use GCC's normal
> +mechanisms to save and restore registers using the stack on function
> +entry and exit. The jump buffer argument @var{buf} holds only the
> +information needed to restore the stack frame, rather than the entire
> +set of saved register values.
I wasn't sure from this whether __builtin_longjmp did actually restore
the values of registers or not. Saying that the jump buffer only
stores the frame information implied not, but...
> +An important caveat is that GCC arranges to save and restore only
> +those registers known to the specific architecture variant being
> +compiled for. This can make @code{__builtin_setjmp} and
> +@code{__builtin_longjmp} more efficient than their library
> +counterparts in some cases, but it can also cause incorrect and
> +mysterious behavior when mixing with code that uses the full register
> +set.
...the combination of these two paragraphs made it less clear.
It sounded like __builtin_longjmp might somehow restore the registers
using save slots in the caller's frame.
Trying it out, AIUI:
- Unlike setjmp and longjmp, __builtin_setjmp and __builtin_longjmp
only save and restore what's in the jump buffer, which as the
documentation says is only enough information to return to the
original stack frame.
- Any function F that calls __builtin_setjmp compensates for this by
saving extra registers on entry and restoring them on exit, in order
to present a normal function interface to F's callers. I.e. it isn't
__builtin_setjmp itself that does the saving, and __builtin_longjmp
doesn't do any restoring. I didn't realise this from reading the above.
Thanks,
Richard