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.

Reply via email to