mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-04 16:50:17 +01:00
shared/glib: reimplement g_atomic_pointer_compare_and_exchange() macro
With glib 2.63.2 and clang 9.0.0 (Fedora 32) we get compile errors:
../clients/cloud-setup/nmcs-provider-ec2.c:51:8: error: incompatible pointer types passing 'typeof ((((void *)0))) *' (aka 'void **') to parameter of type 'const char **' [-Werror,-Wincompatible-pointer-types]
if (!g_atomic_pointer_compare_and_exchange (&base_cached, NULL, base))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gatomic.h:192:44: note: expanded from macro 'g_atomic_pointer_compare_and_exchange'
__atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
^~~~~~~~~~~~~~
../src/devices/bluetooth/nm-bluez-manager.c:2836:2: error: incompatible pointer types passing 'typeof ((((void *)0))) *' (aka 'void **') to parameter of type 'const NMBtVTableNetworkServer **' (aka 'const struct _NMBtVTableNetworkServer **') [-Werror,-Wincompatible-pointer-types]
g_atomic_pointer_compare_and_exchange (&nm_bt_vtable_network_server, NULL, &priv->vtable_network_server);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gatomic.h:192:44: note: expanded from macro 'g_atomic_pointer_compare_and_exchange'
__atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
^~~~~~~~~~~~~~
../src/devices/bluetooth/nm-bluez-manager.c:2853:2: error: passing 'typeof ((&priv->vtable_network_server)) *' (aka 'struct _NMBtVTableNetworkServer **') to parameter of type 'const NMBtVTableNetworkServer **' (aka 'const struct _NMBtVTableNetworkServer **') discards qualifiers in nested pointer types [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
g_atomic_pointer_compare_and_exchange (&nm_bt_vtable_network_server, &priv->vtable_network_server, NULL);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gatomic.h:192:44: note: expanded from macro 'g_atomic_pointer_compare_and_exchange'
__atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
^~~~~~~~~~~~~~
../src/devices/nm-device.c:8857:8: error: incompatible pointer types passing 'typeof ((((void *)0))) *' (aka 'void **') to parameter of type 'GBytes **' (aka 'struct _GBytes **') [-Werror,-Wincompatible-pointer-types]
if (!g_atomic_pointer_compare_and_exchange (&global_duid, NULL, p)) {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gatomic.h:192:44: note: expanded from macro 'g_atomic_pointer_compare_and_exchange'
__atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \
^~~~~~~~~~~~~~
The issue happens because glib passes the "atomic" argument to
__atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
without cast, and clang 9 seems to be picky about const pointers.
Add our own version of the macro that does better casts while also having
better compile time checks for valid arguments.
(cherry picked from commit f5b0713651)
This commit is contained in:
parent
dc981b12a9
commit
d8cc6af058
1 changed files with 26 additions and 0 deletions
|
|
@ -575,4 +575,30 @@ _nm_g_value_unset (GValue *value)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* 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.
|
||||
* Depending on compiler and glib version, glib passes the arguments as they
|
||||
* are to __atomic_compare_exchange_n(). Some clang version don't accept const
|
||||
* 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)
|
||||
{
|
||||
return g_atomic_pointer_compare_and_exchange ((void **) atomic, (void *) oldval, (void *) 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 _oldval = (oldval); \
|
||||
typeof (*_atomic) const _newval = (newval); \
|
||||
\
|
||||
_g_atomic_pointer_compare_and_exchange (_atomic, _oldval, _newval); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* __NM_GLIB_H__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue