gatomic: Tweak __atomic_load*() calls to work with -Wbad-function-cast

When compiling third-party projects with -Wbad-function-cast, the inline
g_atomic_pointer_get() implementation which uses C11 __atomic_load*()
calls on GCC was causing compilation errors like:

   error: cast from function call of type ‘long unsigned int’ to non-matching type ‘void *’

While we don’t want to compile all of GLib with -Wbad-function-cast, we
should support its headers being included in projects which do enable
that warning.

It doesn’t seem to be possible to cast away the warning (e.g. by casting
the function’s result through (void)), so we have to assign to an
intermediate integer of the right size first.

The same has to be done for the bool return value from
__sync_bool_compare_and_swap(). In that case, casting from bool to
gboolean raises a -Wbad-function-cast warning, since gboolean is
secretly int.

The atomic tests have been modified to enable -Wbad-function-cast to
catch regressions of this in future. The GLib build has conversely been
modified to set -Wno-bad-function-cast, just in case people have it set
in their environment CFLAGS.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/glib/issues/1041
This commit is contained in:
Philip Withnall 2018-07-10 17:44:22 +02:00
parent 4a53ed2073
commit 194df27f5a
4 changed files with 17 additions and 5 deletions

View File

@ -3407,6 +3407,7 @@ AC_ARG_ENABLE(compile-warnings,
AS_IF([test "x$enable_compile_warnings" != xno], [
CC_CHECK_FLAGS_APPEND([GLIB_WARN_CFLAGS], [CFLAGS], [\
-Wall -Wstrict-prototypes -Wduplicated-branches -Wmisleading-indentation \
-Wno-bad-function-cast \
-Werror=declaration-after-statement \
-Werror=missing-prototypes -Werror=implicit-function-declaration \
-Werror=pointer-arith -Werror=init-self -Werror=format-security \

View File

@ -109,7 +109,8 @@ G_END_DECLS
#define g_atomic_pointer_get(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
(gpointer) __atomic_load_8 ((atomic), __ATOMIC_SEQ_CST); \
guint64 gapg_temp = __atomic_load_8 ((atomic), __ATOMIC_SEQ_CST); \
(gpointer) gapg_temp; \
}))
#define g_atomic_pointer_set(atomic, newval) \
(G_GNUC_EXTENSION ({ \
@ -127,7 +128,8 @@ G_END_DECLS
#define g_atomic_pointer_get(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
(gpointer) __atomic_load_4 ((atomic), __ATOMIC_SEQ_CST); \
guint32 gapg_temp = __atomic_load_4 ((atomic), __ATOMIC_SEQ_CST); \
(gpointer) gapg_temp; \
}))
#define g_atomic_pointer_set(atomic, newval) \
(G_GNUC_EXTENSION ({ \
@ -186,7 +188,7 @@ G_END_DECLS
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
(void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 1); \
(gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \
__sync_bool_compare_and_swap ((atomic), (oldval), (newval)) ? TRUE : FALSE; \
}))
#define g_atomic_int_add(atomic, val) \
(G_GNUC_EXTENSION ({ \
@ -217,7 +219,7 @@ G_END_DECLS
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
(void) (0 ? (gpointer) *(atomic) : NULL); \
(gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \
__sync_bool_compare_and_swap ((atomic), (oldval), (newval)) ? TRUE : FALSE; \
}))
#define g_atomic_pointer_add(atomic, val) \
(G_GNUC_EXTENSION ({ \

View File

@ -11,6 +11,11 @@
#include <glib.h>
/* We want the g_atomic_pointer_get() macros to work when compiling third party
* projects with -Wbad-function-cast.
* See https://gitlab.gnome.org/GNOME/glib/issues/1041. */
#pragma GCC diagnostic error "-Wbad-function-cast"
static void
test_types (void)
{
@ -191,7 +196,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS
g_assert (ip == 0);
g_atomic_pointer_set (&gs, 0);
gs2 = (gsize) g_atomic_pointer_get (&gs);
vp = g_atomic_pointer_get (&gs);
gs2 = (gsize) vp;
g_assert (gs2 == 0);
res = g_atomic_pointer_compare_and_exchange (&gs, 0, 0);
g_assert (res);

View File

@ -333,6 +333,9 @@ if cc.get_id() == 'gcc' or cc.get_id() == 'clang'
'-Wmisleading-indentation',
'-Wstrict-prototypes',
'-Wunused',
# Due to pervasive use of things like GPOINTER_TO_UINT(), we do not support
# building with -Wbad-function-cast.
'-Wno-bad-function-cast',
'-Werror=declaration-after-statement',
'-Werror=format=2',
'-Werror=format-security',