From fffdb14887629dcaeb72b6d4d8ed30d3d7cc530b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Nov 2022 09:52:10 +0100 Subject: [PATCH] std-aux: make NM_BOOLEAN_EXPR() a constant expression for constant arguments This allows the compiler to see that nm_assert(0) is unreachable code. That is because nm_assert(0) calls NM_LIKELY(0), which calls NM_BOOLEAN_EXPR(0). The latter was a statement expression, which to the compiler was not a constant expression. Hence, this may trigger compiler warnings about uninitialized variables. Let NM_BOOLEAN_EXPR() to be constant, if the arguments are. This can avoid compiler warnings in some cases. Note that __builtin_choose_expr(__builtin_constant_p(...), ...) does not properly work with gcc 4.8 ([1]). Hence only do macro shenanigans with a newer gcc. Then entire point of NM_BOOLEAN_EXPR() is anyway to preserve the "-Wparentheses" warning (while only evaluating the argument once, being safe with nested invocations, propagate constness). If we don't care about "-Wparentheses", it should be the same as (!!(expr)). We can ignore that on non-recent gcc. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449 --- src/libnm-std-aux/nm-std-aux.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libnm-std-aux/nm-std-aux.h b/src/libnm-std-aux/nm-std-aux.h index bef11c86e..fa70fde64 100644 --- a/src/libnm-std-aux/nm-std-aux.h +++ b/src/libnm-std-aux/nm-std-aux.h @@ -175,7 +175,15 @@ typedef uint64_t _nm_bitwise nm_be64_t; NM_UNIQ_T(V, v) = 0; \ NM_UNIQ_T(V, v); \ }) -#define NM_BOOLEAN_EXPR(expr) _NM_BOOLEAN_EXPR_IMPL(NM_UNIQ, expr) + +#if defined(__GNUC__) && (__GNUC__ > 4) +#define NM_BOOLEAN_EXPR(expr) \ + __builtin_choose_expr(__builtin_constant_p(expr), \ + (!!(expr)), \ + _NM_BOOLEAN_EXPR_IMPL(NM_UNIQ, expr)) +#else +#define NM_BOOLEAN_EXPR(expr) (!!(expr)) +#endif #if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) #define NM_LIKELY(expr) __builtin_expect(NM_BOOLEAN_EXPR(expr), 1)