[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