[glib: 1/2] gatomic: Tweak __atomic_load*() calls to work with -Wbad-function-cast



commit 194df27f5aaf07c54d8a16bc8f1380d90b8ead7e
Author: Philip Withnall <withnall endlessm com>
Date:   Tue Jul 10 17:44:22 2018 +0200

    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

 configure.ac        |  1 +
 glib/gatomic.h      | 10 ++++++----
 glib/tests/atomic.c |  8 +++++++-
 meson.build         |  3 +++
 4 files changed, 17 insertions(+), 5 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 87831ae28..ce2d6198e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -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 \
diff --git a/glib/gatomic.h b/glib/gatomic.h
index 8e5efccb4..971176eb9 100644
--- a/glib/gatomic.h
+++ b/glib/gatomic.h
@@ -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 ({                                                       \
diff --git a/glib/tests/atomic.c b/glib/tests/atomic.c
index 35fa705a4..2aafe869f 100644
--- a/glib/tests/atomic.c
+++ b/glib/tests/atomic.c
@@ -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);
diff --git a/meson.build b/meson.build
index 2be847aa4..fa7357d40 100644
--- a/meson.build
+++ b/meson.build
@@ -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',


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]