Sandra Loosemore <san...@codesourcery.com> 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