mirror of
git://git.musl-libc.org/musl
synced 2024-11-23 18:14:19 +08:00
b129cd8690
since 4.1, gcc has had the __returns_twice__ attribute and has required functions which return twice to carry it; however it's always applied it automatically to known setjmp-like function names. clang however does not do this reliably, at least not with -ffreestanding and possibly under other conditions, resulting in silent emission of wrong code. since the symbol name setjmp is in no way special (setjmp is specified as a macro that could expand to use any implementation-specific symbol name or names), a compiler is justified not to do anything special without further hints, and it's reasonable to do what we can to provide such hints. gcc 4.0.x and earlier do not recognize the attribute, so make use conditional on __GNUC__ macros. clang and other gcc-like compilers report (and have always reported) a later "GNUC" version so the preprocessor conditional should function as desired for them as too. undefine the internal macro after use so that nothing abuses it as a public feature.
50 lines
984 B
C
50 lines
984 B
C
#ifndef _SETJMP_H
|
|
#define _SETJMP_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#include <features.h>
|
|
|
|
#include <bits/setjmp.h>
|
|
|
|
typedef struct __jmp_buf_tag {
|
|
__jmp_buf __jb;
|
|
unsigned long __fl;
|
|
unsigned long __ss[128/sizeof(long)];
|
|
} jmp_buf[1];
|
|
|
|
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
|
|
#define __setjmp_attr __attribute__((__returns_twice__))
|
|
#else
|
|
#define __setjmp_attr
|
|
#endif
|
|
|
|
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|
|
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|
|
|| defined(_BSD_SOURCE)
|
|
typedef jmp_buf sigjmp_buf;
|
|
int sigsetjmp (sigjmp_buf, int) __setjmp_attr;
|
|
_Noreturn void siglongjmp (sigjmp_buf, int);
|
|
#endif
|
|
|
|
#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|
|
|| defined(_BSD_SOURCE)
|
|
int _setjmp (jmp_buf) __setjmp_attr;
|
|
_Noreturn void _longjmp (jmp_buf, int);
|
|
#endif
|
|
|
|
int setjmp (jmp_buf) __setjmp_attr;
|
|
_Noreturn void longjmp (jmp_buf, int);
|
|
|
|
#define setjmp setjmp
|
|
|
|
#undef __setjmp_attr
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|