From af4d01b51b282af95e7841d7c02f73ece8cef541 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 2 Nov 2020 10:08:09 +0100 Subject: [PATCH] shared: add a compat implementation for g_atomic_pointer_get() With glib2-2.67.0-1.fc34.x86_64.rpm, clang-11.0.0-2.fc34.x86_64.rpm, we get a failure for g_atomic_pointer_get(): ../shared/nm-glib-aux/nm-hash-utils.c:38:9: error: passing 'typeof (*(&global_seed)) *' (aka 'const unsigned char *volatile *') to parameter of type 'const guint8 **' (aka 'const unsigned char **') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers] g = g_atomic_pointer_get(&global_seed); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/glib-2.0/glib/gatomic.h:112:38: note: expanded from macro 'g_atomic_pointer_get' __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \ ^~~~~~~~~~~~~~~~~ ../shared/nm-glib-aux/nm-hash-utils.c:109:32: error: passing 'typeof (*(&global_seed)) *' (aka 'const unsigned char *volatile *') to parameter of type 'const guint8 **' (aka 'const unsigned char **') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers] return ((*((const guint *) _get_hash_key())) ^ static_seed) ?: 3679500967u; ^~~~~~~~~~~~~~~ ../shared/nm-glib-aux/nm-hash-utils.c:84:14: note: expanded from macro '_get_hash_key' _g = g_atomic_pointer_get(&global_seed); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/glib-2.0/glib/gatomic.h:112:38: note: expanded from macro 'g_atomic_pointer_get' __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \ ^~~~~~~~~~~~~~~~~ ../shared/nm-glib-aux/nm-hash-utils.c:123:9: error: passing 'typeof (*(&global_seed)) *' (aka 'const unsigned char *volatile *') to parameter of type 'const guint8 **' (aka 'const unsigned char **') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers] g = _get_hash_key(); ^~~~~~~~~~~~~~~ ../shared/nm-glib-aux/nm-hash-utils.c:84:14: note: expanded from macro '_get_hash_key' _g = g_atomic_pointer_get(&global_seed); \ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /usr/include/glib-2.0/glib/gatomic.h:112:38: note: expanded from macro 'g_atomic_pointer_get' __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \ ^~~~~~~~~~~~~~~~~ (cherry picked from commit 5e57ea37f0944bfa3441a51afb1bd5e81b8c5b41) (cherry picked from commit 1e4cfba6dc583ebe071506c42f2a04a9915959b0) (cherry picked from commit 446cac18ccb209334644d1347f300599da14c0b9) --- shared/nm-glib-aux/nm-glib.h | 41 ++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/shared/nm-glib-aux/nm-glib.h b/shared/nm-glib-aux/nm-glib.h index 2df5179566..5cac30e12a 100644 --- a/shared/nm-glib-aux/nm-glib.h +++ b/shared/nm-glib-aux/nm-glib.h @@ -565,6 +565,30 @@ _nm_g_value_unset (GValue *value) /*****************************************************************************/ +/* g_atomic_pointer_get() is implemented as a macro, and it is also used for + * (gsize *) arguments. However, that leads to compiler warnings in certain + * configurations. Work around it, by redefining the macro. */ +static inline gpointer +_g_atomic_pointer_get (void **atomic) +{ + return g_atomic_pointer_get (atomic); +} +#undef g_atomic_pointer_get +#define g_atomic_pointer_get(atomic) \ + ({ \ + typeof (*atomic) *const _atomic = (atomic); \ + \ + /* g_atomic_pointer_get() is used by glib also for (gsize *) pointers, + * not only pointers to pointers. We thus don't enforce that (*atomic) + * is a pointer, but of suitable size/alignment. */ \ + \ + G_STATIC_ASSERT (sizeof (*_atomic) == sizeof (gpointer)); \ + G_STATIC_ASSERT (_nm_alignof (*_atomic) == _nm_alignof (gpointer)); \ + (void) (0 ? (gpointer) * (_atomic) : NULL); \ + \ + (typeof (*_atomic)) _g_atomic_pointer_get ((void **) _atomic); \ + }) + /* Glib implements g_atomic_pointer_compare_and_exchange() as a macro. * For one, to inline the atomic operation and also to perform some type checks * on the arguments. @@ -573,20 +597,25 @@ _nm_g_value_unset (GValue *value) * pointers there. Reimplement the macro to get that right, but with stronger * type checks (as we use typeof()). Had one job. */ static inline gboolean -_g_atomic_pointer_compare_and_exchange (volatile void *atomic, - gconstpointer oldval, - gconstpointer newval) +_g_atomic_pointer_compare_and_exchange (void **atomic, + void *oldval, + void *newval) { - return g_atomic_pointer_compare_and_exchange ((void **) atomic, (void *) oldval, (void *) newval); + return g_atomic_pointer_compare_and_exchange (atomic, oldval, newval); } #undef g_atomic_pointer_compare_and_exchange #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ ({ \ - typeof (atomic) const _atomic = (atomic); \ + typeof (*atomic) *const _atomic = (atomic); \ typeof (*_atomic) const _oldval = (oldval); \ typeof (*_atomic) const _newval = (newval); \ + _nm_unused gconstpointer const _val_type_check = _oldval; \ \ - _g_atomic_pointer_compare_and_exchange (_atomic, _oldval, _newval); \ + (void) (0 ? (gpointer) * (_atomic) : NULL); \ + \ + _g_atomic_pointer_compare_and_exchange ((void **) _atomic, \ + (void *) _oldval, \ + (void *) _newval); \ }) /*****************************************************************************/