https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117267
Stas Sergeev <stsp at users dot sourceforge.net> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|INVALID |--- Status|RESOLVED |NEW --- Comment #10 from Stas Sergeev <stsp at users dot sourceforge.net> --- Yes, that seems to work, thanks. But this doesn't mean there is no bug. Here's the updated test-case: --- #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <ucontext.h> typedef struct __jmp_buf { void *buf[5]; } jmp_buf[1]; static ucontext_t uc; __attribute__((noinline)) static int setjmp(jmp_buf env) { int rc = __builtin_setjmp(env[0].buf); if (rc) setcontext(&uc); return rc; } static jmp_buf jb; static void foo(void) { printf("before jump\n"); __builtin_longjmp(jb[0].buf, 1); } static void bar(void) { printf("swapcontext worked\n"); exit(0); } int main(void) { if (setjmp(jb)) printf("Jumped\n"); else { getcontext(&uc); uc.uc_stack.ss_sp = malloc(8192); uc.uc_stack.ss_size = 8192; makecontext(&uc, bar, 0); foo(); } return 0; } --- The idea is to leave the setjmp() uninlined and recover the stack with swapcontext(). It works properly w/o optimization, but generates bad code (shown in prev msg) with -O2. clang generates the correct code with any -O.