[Bug c/59039] Undocumented __builtin_longjmp/__builtin_setjmp

hjl.tools at gmail dot com gcc-bugzilla@gcc.gnu.org
Thu Nov 7 16:27:00 GMT 2013


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59039

--- Comment #10 from H.J. Lu <hjl.tools at gmail dot com> ---
(In reply to Eric Botcazou from comment #9)
> > What restrictions do they have? Can they be used within the
> > same function? Can they be used within functions with parameters?
> 
> The only restriction I know of is that they cannot be in the same function,
> it's even enforced by the inliner:
> 
> 	  case BUILT_IN_LONGJMP:
> 	    /* We can't inline functions that call __builtin_longjmp at
> 	       all.  The non-local goto machinery really requires the
> 	       destination be in a different function.  If we allow the
> 	       function calling __builtin_longjmp to be inlined into the
> 	       function calling __builtin_setjmp, Things will Go Awry.  */
> 	    inline_forbidden_reason
> 	      = G_("function %q+F can never be inlined because "
> 		   "it uses setjmp-longjmp exception handling");

But gcc doesn't issue anything for this testcase:

[hjl@gnu-hsw-1 tmp]$ cat z.c
#include <setjmp.h>

extern jmp_buf buf;

int
foo (int i)
{
  int j = i + 1;
  if (__builtin_setjmp (buf))
    {
      j += 1;
      __builtin_longjmp (buf, 1);
    }

  return j + i;
}
[hjl@gnu-hsw-1 tmp]$ gcc -S -O2 z.c -Wall
[hjl@gnu-hsw-1 tmp]$ 

For this testcase:

[hjl@gnu-hsw-1 tmp]$ cat i.c
#include <setjmp.h>

extern jmp_buf buf;

int
foo (int i)
{
  int j = i + 1;
  if (!__builtin_setjmp (buf))
    {
      j += 1;
    }

  return j + i;
}
[hjl@gnu-hsw-1 tmp]$ gcc -O2 -S i.c
[hjl@gnu-hsw-1 tmp]$ cat i.s
    .file    "i.c"
    .text
    .p2align 4,,15
    .globl    foo
    .type    foo, @function
foo:
.LFB0:
    .cfi_startproc
.L4:
.L2:
    movq    %rsp, buf(%rip)
    movq    $.L2, buf+8(%rip)
    leal    2(%rdi,%rdi), %eax
    movq    %rsp, buf+16(%rip)
    ret
    .cfi_endproc
.LFE0:
    .size    foo, .-foo

%rdi holds the function parameter 'i'.  But when __builtin_longjmp is
called, %rdi can have some random value.  GCC doesn't save %rdi first.


More information about the Gcc-bugs mailing list