X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fshared%2Fmacro.h;h=32cf714857809b5ec591cd484c9e1c0671654529;hp=dfbc20142f753172ee8708f5e5aa94eca27fa66b;hb=d442e2ec6e896c312bc616be7607332d978a45c9;hpb=348ced909724a1331b85d57aede80a102a00e428 diff --git a/src/shared/macro.h b/src/shared/macro.h index dfbc20142..32cf71485 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -46,6 +46,30 @@ #define _alignas_(x) __attribute__((aligned(__alignof(x)))) #define _cleanup_(x) __attribute__((cleanup(x))) +/* Temporarily disable some warnings */ +#define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wdeclaration-after-statement\"") + +#define DISABLE_WARNING_FORMAT_NONLITERAL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wformat-nonliteral\"") + +#define DISABLE_WARNING_MISSING_PROTOTYPES \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wmissing-prototypes\"") + +#define DISABLE_WARNING_NONNULL \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wnonnull\"") + +#define DISABLE_WARNING_SHADOW \ + _Pragma("GCC diagnostic push"); \ + _Pragma("GCC diagnostic ignored \"-Wshadow\"") + +#define REENABLE_WARNING \ + _Pragma("GCC diagnostic pop") + /* automake test harness */ #define EXIT_TEST_SKIP 77 @@ -78,7 +102,20 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { return ((l + ali - 1) & ~(ali - 1)); } -#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p)) +#define ALIGN_TO_PTR(p, ali) ((void*) ALIGN_TO((unsigned long) p, ali)) + +/* align to next higher power-of-2 (except for: 0 => 0, overflow => 0) */ +static inline unsigned long ALIGN_POWER2(unsigned long u) { + /* clz(0) is undefined */ + if (u == 1) + return 1; + + /* left-shift overflow is undefined */ + if (__builtin_clzl(u - 1UL) < 1) + return 0; + + return 1UL << (sizeof(u) * 8 - __builtin_clzl(u - 1UL)); +} #define ELEMENTSOF(x) (sizeof(x)/sizeof((x)[0])) @@ -154,9 +191,20 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) { } while (false) #if defined(static_assert) -#define assert_cc(expr) static_assert(expr, #expr) +/* static_assert() is sometimes defined in a way that trips up + * -Wdeclaration-after-statement, hence let's temporarily turn off + * this warning around it. */ +#define assert_cc(expr) \ + DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \ + static_assert(expr, #expr); \ + REENABLE_WARNING #else -#define assert_cc(expr) struct UNIQUE(_assert_struct_) { char x[(expr) ? 0 : -1]; }; +#define assert_cc(expr) \ + DISABLE_WARNING_DECLARATION_AFTER_STATEMENT; \ + struct UNIQUE(_assert_struct_) { \ + char x[(expr) ? 0 : -1]; \ + }; \ + REENABLE_WARNING #endif #define assert_return(expr, r) \ @@ -293,13 +341,14 @@ do { \ #define SET_FLAG(v, flag, b) \ (v) = (b) ? ((v) | (flag)) : ((v) & ~(flag)) -#define IN_SET(x, ...) \ +#define IN_SET(x, y, ...) \ ({ \ - const typeof(x) _x = (x); \ + const typeof(y) _y = (y); \ + const typeof(_y) _x = (x); \ unsigned _i; \ bool _found = false; \ - for (_i = 0; _i < sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \ - if (((const typeof(_x)[]) { __VA_ARGS__ })[_i] == _x) { \ + for (_i = 0; _i < 1 + sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \ + if (((const typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \ _found = true; \ break; \ } \