https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117469

Luke Shumaker <lukeshu at lukeshu dot com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lukeshu at lukeshu dot com

--- Comment #3 from Luke Shumaker <lukeshu at lukeshu dot com> ---
The call to the inner function that `returns_twice` doesn't need to be a
tail-call; just that its return value is returned by the outer function.

    int ret = setjmp(env);
    ...do more things...
    return ret;

Anyway, here's a test-case:

#include <setjmp.h>
#include <stdio.h>

/* setjmp wrapper
*************************************************************/

typedef struct {
        jmp_buf raw;
} plat_jmp_buf;

#if 1
/* fails */
__attribute__((returns_twice)) int plat_setjmp(plat_jmp_buf *env) {
        return sigsetjmp(env->raw, 0);
}
#else
/* passes */
#  define plat_setjmp(env) sigsetjmp((env)->raw, 0)
#endif

__attribute__((noreturn)) void plat_longjmp(plat_jmp_buf *env, int val) {
        siglongjmp(env->raw, val);
}

/* application
****************************************************************/

typedef void (*fn_t)(void);

plat_jmp_buf env;

void outer(fn_t fn) {
        if (!plat_setjmp(&env)) {
                fn();
                puts("fail");
        } else {
                puts("pass");
        }
}

__attribute__((noreturn)) void inner() {
        plat_longjmp(&env, 1);
}

int main() {
        outer(inner);
        return 0;
}

Reply via email to