Message ID | 610c694c-9610-b193-9597-64509e06e761@codesourcery.com |
---|---|
State | New |
Headers | show |
Series | [doc,rfc] document __builtin_setjmp and __builtin_longjmp | expand |
On Nov 30 2018, Sandra Loosemore <sandra@codesourcery.com> wrote:
> +@code{__builtin_setjmp} and @code{__builtin_longjmp} use GCC's normal
Please avoid starting the sentence with a non-capital.
Andreas.
On 12/1/18 2:27 AM, Andreas Schwab wrote: > On Nov 30 2018, Sandra Loosemore <sandra@codesourcery.com> wrote: > >> +@code{__builtin_setjmp} and @code{__builtin_longjmp} use GCC's normal > > Please avoid starting the sentence with a non-capital. OK, I can fix that easily enough. I was really looking more for comments on focus, correctness, terminology, etc though. :-) -Sandra
On 11/30/18 9:57 PM, Sandra Loosemore wrote: > 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 looks pretty good to me. It contains the most important info, specifically that the builtin setjmp/longjmp are really for internal purposes. jeff
Sandra Loosemore <sandra@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
Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 266688) +++ gcc/doc/extend.texi (working copy) @@ -27,6 +27,7 @@ extensions, accepted by GCC in C90 mode * Local Labels:: Labels local to a block. * Labels as Values:: Getting pointers to labels, and computed gotos. * Nested Functions:: Nested function in GNU C. +* Nonlocal Gotos:: Nonlocal gotos. * Constructing Calls:: Dispatching a call to another function. * Typeof:: @code{typeof}: referring to the type of an expression. * Conditionals:: Omitting the middle operand of a @samp{?:} expression. @@ -520,6 +521,61 @@ bar (int *array, int offset, int size) @} @end smallexample +@node Nonlocal Gotos +@section Nonlocal Gotos +@cindex nonlocal gotos + +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. + +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. + +You should declare the jump buffer argument @var{buf} to the +built-in functions as: + +@smallexample +#include <stdint.h> +intptr_t @var{buf}[5]; +@end smallexample + +@deftypefn {Built-in Function} {int} __builtin_setjmp (intptr_t *@var{buf}) +This function saves the current stack context in @var{buf}. +@code{__builtin_setjmp} returns 0 when returning directly, +and 1 when returning from @code{__builtin_longjmp} using the same +@var{buf}. +@end deftypefn + +@deftypefn {Built-in Function} {void} __builtin_longjmp (intptr_t *@var{buf}, int @var{val}) +This function restores the stack context in @var{buf}, +saved by a previous call to @code{__builtin_setjmp}. After +@code{__builtin_longjmp} is finished, the program resumes execution as +if the matching @code{__builtin_setjmp} returns the value @var{val}, +which must be 1. + +Because @code{__builtin_longjmp} depends on the function return +mechanism to restore the stack context, it cannot be called +from the same function calling @code{__builtin_setjmp} to +initialize @var{buf}. It can only be called from a function called +(directly or indirectly) from the function calling @code{__builtin_setjmp}. +@end deftypefn + @node Constructing Calls @section Constructing Function Calls @cindex constructing calls