From 2559a9711ca7f681688c107c1cb456b544a7c4b6 Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Sun, 3 Jan 2021 08:47:12 +0000 Subject: [PATCH 1/2] macros: add wrappers for more GCC/Clang attributes/pragmas/builtins --- macros.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 7 deletions(-) diff --git a/macros.h b/macros.h index d4621bd5..0a355ceb 100644 --- a/macros.h +++ b/macros.h @@ -1,5 +1,6 @@ #pragma once +#define DO_PRAGMA(x) _Pragma(#x) #define VERCMP(x, y, cx, cy) ((cx > x) || ((cx == x) && (cy >= y))) #if defined(__GNUC__) && defined(__GNUC_MINOR__) @@ -8,6 +9,12 @@ #define GNUC_AT_LEAST(x, y) 0 #endif +#if defined(__clang_major__) && defined(__clang_minor__) + #define CLANG_AT_LEAST(x, y) VERCMP(x, y, __clang_major__, __clang_minor__) +#else + #define CLANG_AT_LEAST(x, y) 0 +#endif + #ifdef __has_attribute #define HAS_ATTRIBUTE(x) __has_attribute(x) #else @@ -26,13 +33,7 @@ #define UNUSED #endif -#if HAS_ATTRIBUTE(noinline) - #define NOINLINE __attribute__((noinline)) -#else - #define NOINLINE -#endif - -#if HAS_ATTRIBUTE(const) +#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(const) #define CONST __attribute__((__const__)) #else #define CONST @@ -60,6 +61,18 @@ #define unlikely(x) (x) #endif +#if GNUC_AT_LEAST(3, 1) || HAS_ATTRIBUTE(noinline) + #define NOINLINE __attribute__((__noinline__)) +#else + #define NOINLINE +#endif + +#if GNUC_AT_LEAST(3, 1) || HAS_ATTRIBUTE(always_inline) + #define ALWAYS_INLINE __attribute__((__always_inline__)) +#else + #define ALWAYS_INLINE +#endif + #if GNUC_AT_LEAST(3, 3) || HAS_ATTRIBUTE(nonnull) #define NONNULL_ARGS __attribute__((__nonnull__)) #define NONNULL_ARG(...) __attribute__((__nonnull__(__VA_ARGS__))) @@ -74,18 +87,42 @@ #define WARN_UNUSED_RESULT #endif +#if GNUC_AT_LEAST(4, 1) || HAS_ATTRIBUTE(flatten) + #define FLATTEN __attribute__((__flatten__)) +#else + #define FLATTEN +#endif + +#if GNUC_AT_LEAST(4, 3) || HAS_ATTRIBUTE(hot) + #define HOT __attribute__((__hot__)) +#else + #define HOT +#endif + #if GNUC_AT_LEAST(4, 3) || HAS_ATTRIBUTE(cold) #define COLD __attribute__((__cold__)) #else #define COLD #endif +#if GNUC_AT_LEAST(4, 5) || HAS_BUILTIN(__builtin_unreachable) + #define UNREACHABLE() __builtin_unreachable() +#else + #define UNREACHABLE() +#endif + #if GNUC_AT_LEAST(5, 0) || HAS_ATTRIBUTE(returns_nonnull) #define RETURNS_NONNULL __attribute__((__returns_nonnull__)) #else #define RETURNS_NONNULL #endif +#if HAS_ATTRIBUTE(diagnose_if) + #define DIAGNOSE_IF(x) __attribute__((diagnose_if((x), (#x), "error"))) +#else + #define DIAGNOSE_IF(x) +#endif + #define XMALLOC MALLOC RETURNS_NONNULL WARN_UNUSED_RESULT #define XSTRDUP XMALLOC NONNULL_ARGS @@ -96,3 +133,29 @@ #else #define NORETURN #endif + +#if CLANG_AT_LEAST(3, 6) + #define UNROLL_LOOP(n) DO_PRAGMA(clang loop unroll_count(n)) +#elif GNUC_AT_LEAST(8, 0) + #define UNROLL_LOOP(n) DO_PRAGMA(GCC unroll (n)) +#else + #define UNROLL_LOOP(n) +#endif + +#ifdef __clang__ + #define IGNORE_WARNING(wflag) \ + DO_PRAGMA(clang diagnostic push) \ + DO_PRAGMA(clang diagnostic ignored "-Wunknown-pragmas") \ + DO_PRAGMA(clang diagnostic ignored "-Wunknown-warning-option") \ + DO_PRAGMA(clang diagnostic ignored wflag) + #define UNIGNORE_WARNINGS DO_PRAGMA(clang diagnostic pop) +#elif GNUC_AT_LEAST(4, 6) + #define IGNORE_WARNING(wflag) \ + DO_PRAGMA(GCC diagnostic push) \ + DO_PRAGMA(GCC diagnostic ignored "-Wpragmas") \ + DO_PRAGMA(GCC diagnostic ignored wflag) + #define UNIGNORE_WARNINGS DO_PRAGMA(GCC diagnostic pop) +#else + #define IGNORE_WARNING(wflag) + #define UNIGNORE_WARNINGS +#endif From 39b2e46e72ad82ec2971b859eae75562751f8464 Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Sun, 3 Jan 2021 08:56:47 +0000 Subject: [PATCH 2/2] Use wrappers from macros.h instead of bare GCC attributes/pragmas --- box-drawing.c | 9 ++------- macros.h | 12 ++++++++++++ render.c | 2 +- vt.c | 9 ++------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/box-drawing.c b/box-drawing.c index e655bfdc..8640fc4c 100644 --- a/box-drawing.c +++ b/box-drawing.c @@ -1861,10 +1861,7 @@ draw_sextant(wchar_t wc, struct buf *buf) static void draw_glyph(wchar_t wc, struct buf *buf) { -#if defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpedantic" -#endif + IGNORE_WARNING("-Wpedantic") switch (wc) { case 0x2500: draw_box_drawings_light_horizontal(buf); break; @@ -2037,9 +2034,7 @@ draw_glyph(wchar_t wc, struct buf *buf) case 0x1fb00 ... 0x1fb3b: draw_sextant(wc, buf); break; } -#if defined(__GNUC__) - #pragma GCC diagnostic pop -#endif + UNIGNORE_WARNINGS } struct fcft_glyph * COLD diff --git a/macros.h b/macros.h index 0a355ceb..1fd82b77 100644 --- a/macros.h +++ b/macros.h @@ -45,6 +45,18 @@ #define MALLOC #endif +#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(constructor) + #define CONSTRUCTOR __attribute__((__constructor__)) +#else + #define CONSTRUCTOR +#endif + +#if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(destructor) + #define DESTRUCTOR __attribute__((__destructor__)) +#else + #define DESTRUCTOR +#endif + #if GNUC_AT_LEAST(3, 0) || HAS_ATTRIBUTE(format) #define PRINTF(x) __attribute__((__format__(__printf__, (x), (x + 1)))) #define VPRINTF(x) __attribute__((__format__(__printf__, (x), 0))) diff --git a/render.c b/render.c index 680dd278..ed4854f0 100644 --- a/render.c +++ b/render.c @@ -80,7 +80,7 @@ render_destroy(struct renderer *renderer) free(renderer); } -static void __attribute__((destructor)) +static void DESTRUCTOR log_presentation_statistics(void) { if (presentation_statistics.total == 0) diff --git a/vt.c b/vt.c index 120b9c98..e8e10b2f 100644 --- a/vt.c +++ b/vt.c @@ -750,10 +750,7 @@ action_utf8_44(struct terminal *term, uint8_t c) action_utf8_print(term, term->vt.utf8); } -#if defined(__GNUC__) - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wpedantic" -#endif +IGNORE_WARNING("-Wpedantic") static enum state state_ground_switch(struct terminal *term, uint8_t data) @@ -1277,9 +1274,7 @@ state_utf8_43_switch(struct terminal *term, uint8_t data) } } -#if defined(__GNUC__) - #pragma GCC diagnostic pop -#endif +UNIGNORE_WARNINGS void vt_from_slave(struct terminal *term, const uint8_t *data, size_t len)