diff --git a/include/assert.h b/include/assert.h index bad2ccd04cf3bbc9abe39c2f26ef9b8680d60a9e..30a43d68fae741b6a8b05cd4451da70f984e4fba 100644 --- a/include/assert.h +++ b/include/assert.h @@ -1,5 +1,12 @@ #undef assert +#if __STDC_VERSION__ >= 201112L +#elif defined(__GNUC__) +#define _Noreturn __attribute__((__noreturn__)) +#else +#define _Noreturn +#endif + #ifdef NDEBUG #define assert(x) (void)0 #else @@ -10,7 +17,7 @@ extern "C" { #endif -void __assert_fail (const char *, const char *, int, const char *); +_Noreturn void __assert_fail (const char *, const char *, int, const char *); #ifdef __cplusplus } diff --git a/include/err.h b/include/err.h index 5e33f9e42e4508e2c6c53214e714388d73923471..a6505c366820cd74007bd83007f957e6257692ba 100644 --- a/include/err.h +++ b/include/err.h @@ -1,6 +1,13 @@ #ifndef _ERR_H #define _ERR_H +#if __STDC_VERSION__ >= 201112L +#elif defined(__GNUC__) +#define _Noreturn __attribute__((__noreturn__)) +#else +#define _Noreturn +#endif + #include #ifdef __cplusplus @@ -12,10 +19,10 @@ void vwarn(const char *, va_list); void warnx(const char *, ...); void vwarnx(const char *, va_list); -void err(int, const char *, ...); -void verr(int, const char *, va_list); -void errx(int, const char *, ...); -void verrx(int, const char *, va_list); +_Noreturn void err(int, const char *, ...); +_Noreturn void verr(int, const char *, va_list); +_Noreturn void errx(int, const char *, ...); +_Noreturn void verrx(int, const char *, va_list); #ifdef __cplusplus } diff --git a/include/pthread.h b/include/pthread.h index 417156c883d56481d34085f68155a22cbd0460c0..bc0d9f1c32bc3ef8a8ca6ea409eb4d5e0462434a 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -10,6 +10,13 @@ extern "C" { #define __restrict #endif +#if __STDC_VERSION__ >= 201112L +#elif defined(__GNUC__) +#define _Noreturn __attribute__((__noreturn__)) +#else +#define _Noreturn +#endif + #define __NEED_time_t #define __NEED_clockid_t #define __NEED_struct_timespec @@ -79,7 +86,7 @@ extern "C" { int pthread_create(pthread_t *__restrict, const pthread_attr_t *__restrict, void *(*)(void *), void *__restrict); int pthread_detach(pthread_t); -void pthread_exit(void *); +_Noreturn void pthread_exit(void *); int pthread_join(pthread_t, void **); #ifdef __GNUC__ diff --git a/include/setjmp.h b/include/setjmp.h index 8ec5c6f185705390dbbf56a78e0010e04ad1a8a0..e5877b4468f90f4c39efa1d959451f12534cdf7d 100644 --- a/include/setjmp.h +++ b/include/setjmp.h @@ -24,14 +24,14 @@ typedef struct { unsigned long __ss[128/sizeof(long)]; } sigjmp_buf[1]; int sigsetjmp (sigjmp_buf, int); -void siglongjmp (sigjmp_buf, int); +_Noreturn void siglongjmp (sigjmp_buf, int); #endif #if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ || defined(_BSD_SOURCE) int _setjmp (jmp_buf); -void _longjmp (jmp_buf, int); +_Noreturn void _longjmp (jmp_buf, int); #endif diff --git a/include/unistd.h b/include/unistd.h index ecb23f81e6e453f32758017b42c8acbf64473d3b..20ba6ccbf94be32cf2444a5099b2c0a77f72a88a 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -11,6 +11,13 @@ extern "C" { #define __restrict #endif +#if __STDC_VERSION__ >= 201112L +#elif defined(__GNUC__) +#define _Noreturn __attribute__((__noreturn__)) +#else +#define _Noreturn +#endif + #define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 @@ -90,7 +97,7 @@ int execl(const char *, const char *, ...); int execvp(const char *, char *const []); int execlp(const char *, const char *, ...); int fexecve(int, char *const [], char *const []); -void _exit(int); +_Noreturn void _exit(int); pid_t getpid(void); pid_t getppid(void); diff --git a/src/exit/_Exit.c b/src/exit/_Exit.c index c00a2ffbc798b2a5243c017d9b5292fb2afcc2bb..7a6115c7bbc71265929b20c8817d8476ee184b39 100644 --- a/src/exit/_Exit.c +++ b/src/exit/_Exit.c @@ -4,5 +4,5 @@ _Noreturn void _Exit(int ec) { __syscall(SYS_exit_group, ec); - __syscall(SYS_exit, ec); + for (;;) __syscall(SYS_exit, ec); } diff --git a/src/exit/assert.c b/src/exit/assert.c index e87442a7c50d9ca8fdf267d7c6038780941c56d3..49b0dc3ec434c68a92ad3c38f087aec74c45e4e3 100644 --- a/src/exit/assert.c +++ b/src/exit/assert.c @@ -1,7 +1,7 @@ #include #include -void __assert_fail(const char *expr, const char *file, int line, const char *func) +_Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func) { fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line); fflush(NULL); diff --git a/src/linux/err.c b/src/linux/err.c index c291136dec3af739d5c46e8604c91ca6bc976f65..0f7485388ff0fd892b8937f464a5fe33b0d0c719 100644 --- a/src/linux/err.c +++ b/src/linux/err.c @@ -15,13 +15,13 @@ void vwarnx(const char *fmt, va_list ap) putc('\n', stderr); } -void verr(int status, const char *fmt, va_list ap) +_Noreturn void verr(int status, const char *fmt, va_list ap) { vwarn(fmt, ap); exit(status); } -void verrx(int status, const char *fmt, va_list ap) +_Noreturn void verrx(int status, const char *fmt, va_list ap) { vwarnx(fmt, ap); exit(status); @@ -43,7 +43,7 @@ void warnx(const char *fmt, ...) va_end(ap); } -void err(int status, const char *fmt, ...) +_Noreturn void err(int status, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -51,7 +51,7 @@ void err(int status, const char *fmt, ...) va_end(ap); } -void errx(int status, const char *fmt, ...) +_Noreturn void errx(int status, const char *fmt, ...) { va_list ap; va_start(ap, fmt); diff --git a/src/signal/siglongjmp.c b/src/signal/siglongjmp.c index e9a6131417de5624662c6d899f74d1d0de5c527b..d0e4f67d3bccf9c2f201ca30e1cf9f23a839a616 100644 --- a/src/signal/siglongjmp.c +++ b/src/signal/siglongjmp.c @@ -3,7 +3,7 @@ #include #include "syscall.h" -void siglongjmp(sigjmp_buf buf, int ret) +_Noreturn void siglongjmp(sigjmp_buf buf, int ret) { if (buf->__fl) __syscall(SYS_rt_sigprocmask, SIG_SETMASK, buf->__ss, 0, __SYSCALL_SSLEN); diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 4567b41c68d3458376b6235d0e355c6ab86125ba..d8b8f0fcf8383ce3db3cddb833983c077e904f7e 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -8,7 +8,7 @@ weak_alias(dummy_0, __synccall_lock); weak_alias(dummy_0, __synccall_unlock); weak_alias(dummy_0, __pthread_tsd_run_dtors); -void pthread_exit(void *result) +_Noreturn void pthread_exit(void *result) { pthread_t self = pthread_self(); int n; @@ -43,7 +43,7 @@ void pthread_exit(void *result) __unmapself(self->map_base, self->map_size); } - __syscall(SYS_exit, 0); + for (;;) __syscall(SYS_exit, 0); } void __do_cleanup_push(struct __ptcb *cb) diff --git a/src/unistd/_exit.c b/src/unistd/_exit.c index d2e84c4cae4c8ae16404857a6905625d9da98d65..769948232e46e8be03cd2530f37b60b62d864ae1 100644 --- a/src/unistd/_exit.c +++ b/src/unistd/_exit.c @@ -1,7 +1,7 @@ #include #include -void _exit(int status) +_Noreturn void _exit(int status) { _Exit(status); }