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; }