diff --git a/asm/error.c b/asm/error.c index 45811a8d..1f91cd78 100644 --- a/asm/error.c +++ b/asm/error.c @@ -87,7 +87,7 @@ void nasm_error(int severity, const char *fmt, ...) va_end(ap); } -no_return nasm_fatal(int flags, const char *fmt, ...) +fatal_func nasm_fatal(int flags, const char *fmt, ...) { va_list ap; @@ -96,7 +96,7 @@ no_return nasm_fatal(int flags, const char *fmt, ...) abort(); /* We should never get here */ } -no_return nasm_panic(int flags, const char *fmt, ...) +fatal_func nasm_panic(int flags, const char *fmt, ...) { va_list ap; @@ -105,12 +105,12 @@ no_return nasm_panic(int flags, const char *fmt, ...) abort(); /* We should never get here */ } -no_return nasm_panic_from_macro(const char *file, int line) +fatal_func nasm_panic_from_macro(const char *file, int line) { nasm_panic(ERR_NOFILE, "Internal error at %s:%d\n", file, line); } -no_return nasm_assert_failed(const char *file, int line, const char *msg) +fatal_func nasm_assert_failed(const char *file, int line, const char *msg) { nasm_panic(0, "assertion %s failed at %s:%d", msg, file, line); } diff --git a/configure.ac b/configure.ac index 1f492103..4e27bb3e 100644 --- a/configure.ac +++ b/configure.ac @@ -223,6 +223,7 @@ PA_FUNC_ATTRIBUTE(alloc_size, (1)) PA_FUNC_ATTRIBUTE(format, [(printf,1,2)], int, [const char *, ...], ["%d",1]) PA_FUNC_ATTRIBUTE(const) PA_FUNC_ATTRIBUTE(pure) +PA_FUNC_ATTRIBUTE(cold) PA_FUNC_ATTRIBUTE_ERROR dnl diff --git a/include/compiler.h b/include/compiler.h index 6e919d3d..6c7e20c5 100644 --- a/include/compiler.h +++ b/include/compiler.h @@ -285,6 +285,22 @@ size_t strnlen(const char *s, size_t maxlen); # define no_return void #endif +/* + * How to tell the compiler that a function is unlikely to be executed. + * This differs from unlikely() in that it is applied to a function call, + * not a boolean condition. + */ +#ifndef HAVE_FUNC_ATTRIBUTE_COLD +# define unlikely_func __attribute__((cold)) +#else +# define unlikely_func +#endif + +/* + * A fatal function is both unlikely and no_return + */ +#define fatal_func no_return unlikely_func + /* * How to tell the compiler that a function takes a printf-like string */ diff --git a/include/error.h b/include/error.h index c49377eb..55cb1278 100644 --- a/include/error.h +++ b/include/error.h @@ -44,9 +44,9 @@ * An error reporting function should look like this. */ void printf_func(2, 3) nasm_error(int severity, const char *fmt, ...); -no_return printf_func(2, 3) nasm_fatal(int flags, const char *fmt, ...); -no_return printf_func(2, 3) nasm_panic(int flags, const char *fmt, ...); -no_return nasm_panic_from_macro(const char *file, int line); +fatal_func printf_func(2, 3) nasm_fatal(int flags, const char *fmt, ...); +fatal_func printf_func(2, 3) nasm_panic(int flags, const char *fmt, ...); +fatal_func nasm_panic_from_macro(const char *file, int line); #define panic() nasm_panic_from_macro(__FILE__, __LINE__); typedef void (*vefunc) (int severity, const char *fmt, va_list ap); diff --git a/include/nasmlib.h b/include/nasmlib.h index 78bb1e48..ae0473a1 100644 --- a/include/nasmlib.h +++ b/include/nasmlib.h @@ -111,7 +111,7 @@ void nasm_write(const void *, size_t, FILE *); /* * NASM assert failure */ -no_return nasm_assert_failed(const char *, int, const char *); +fatal_func nasm_assert_failed(const char *, int, const char *); #define nasm_assert(x) \ do { \ if (unlikely(!(x))) \