diff mbox series

[doc,rfc] document __builtin_setjmp and __builtin_longjmp

Message ID 610c694c-9610-b193-9597-64509e06e761@codesourcery.com
State New
Headers show
Series [doc,rfc] document __builtin_setjmp and __builtin_longjmp | expand

Commit Message

Sandra Loosemore Dec. 1, 2018, 4:57 a.m. UTC
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.

-Sandra

Comments

Andreas Schwab Dec. 1, 2018, 9:27 a.m. UTC | #1
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.
Sandra Loosemore Dec. 1, 2018, 7:59 p.m. UTC | #2
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
Jeff Law Dec. 3, 2018, 6:49 p.m. UTC | #3
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
Richard Sandiford Dec. 4, 2018, 3:08 p.m. UTC | #4
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
diff mbox series

Patch

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