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