all: merge branch 'th/unreachable-asserts'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1470
This commit is contained in:
Thomas Haller
2022-12-06 17:09:38 +01:00
2 changed files with 47 additions and 18 deletions

View File

@@ -530,7 +530,12 @@ nm_str_realloc(char *str)
/* redefine assertions to use g_assert*() */
#undef _nm_assert_fail
#define _nm_assert_fail(msg) \
g_assertion_message_expr(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg)
G_STMT_START \
{ \
g_assertion_message_expr(G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg); \
_nm_unreachable_code(); \
} \
G_STMT_END
#undef _NM_ASSERT_FAIL_ENABLED
#ifndef G_DISABLE_ASSERT

View File

@@ -75,6 +75,14 @@
/*****************************************************************************/
/* This is mainly used in case of failed assertions. Usually assert() itself
* already ensures that the code path is marked as unreachable, however with
* NDEBUG that might not be the case. We want to mark the code as unreachable
* even with NDEBUG/G_DISABLE_ASSERT. */
#define _nm_unreachable_code() __builtin_unreachable()
/*****************************************************************************/
#ifndef _NM_CC_SUPPORT_AUTO_TYPE
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)))
#define _NM_CC_SUPPORT_AUTO_TYPE 1
@@ -175,7 +183,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)
@@ -226,10 +242,12 @@ _nm_assert_fail_internal(const char *assertion,
#define _NM_ASSERT_FAIL_ENABLED 1
#define _nm_assert_fail(msg) __assert_fail((msg), __FILE__, __LINE__, __func__)
#else
#define _NM_ASSERT_FAIL_ENABLED 1
#define _NM_ASSERT_FAIL_ENABLED 0
#define _nm_assert_fail(msg) \
do { \
_nm_unused const char *_msg = (msg); \
\
_nm_unreachable_code(); \
} while (0)
#endif
@@ -243,6 +261,11 @@ _nm_assert_fail_internal(const char *assertion,
* As such, nm_assert() is async-signal-safe (provided @cond is, and
* the assertion does not fail). */ \
if (NM_MORE_ASSERTS_EFFECTIVE == 0) { \
if (__builtin_constant_p(cond) && !(cond)) { \
/* Constant expressions are still evaluated and result
* in unreachable code. This handles nm_assert(FALSE). */ \
_nm_unreachable_code(); \
} \
/* pass */ \
} else if (NM_LIKELY(cond)) { \
/* pass */ \
@@ -261,11 +284,12 @@ _nm_assert_fail_internal(const char *assertion,
* the assertion does not fail). */ \
if (NM_LIKELY(cond)) { \
/* pass */ \
} else if (NM_MORE_ASSERTS_EFFECTIVE == 0) { \
/* pass */ \
} else { \
if (NM_MORE_ASSERTS_EFFECTIVE != 0) { \
_nm_assert_fail(#cond); \
} \
_nm_unreachable_code(); \
} \
1; \
})