[glib: 2/4] gatomic: Fix strict aliasing problems with g_atomic_pointer_{get, set}()
- From: Sebastian Dröge <sdroege src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib: 2/4] gatomic: Fix strict aliasing problems with g_atomic_pointer_{get, set}()
- Date: Fri, 18 Oct 2019 14:00:54 +0000 (UTC)
commit 3251cce524dbde48e0e5ea0df3169f76e10d0794
Author: Philip Withnall <withnall endlessm com>
Date: Mon Oct 7 16:23:02 2019 +0100
gatomic: Fix strict aliasing problems with g_atomic_pointer_{get,set}()
Casting pointer types around is a bit fiddly when you also end up
dereferencing them. Take advantage of the fact that the
`__atomic_load()` and `__atomic_store()` built-ins are polymorphic, and
use `__typeof__()` to ensure that the atomic pointer macros use the
caller-provided types internally, and hence any type mismatches are
entirely the caller’s fault rather than ours.
This also means that the `__atomic_{load,store}()` built-ins have the
right alignment and width data from the caller-provided types, in case
that’s needed.
Signed-off-by: Philip Withnall <withnall endlessm com>
glib/gatomic.h | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
---
diff --git a/glib/gatomic.h b/glib/gatomic.h
index 61a99adf2..304e855b1 100644
--- a/glib/gatomic.h
+++ b/glib/gatomic.h
@@ -103,20 +103,41 @@ G_END_DECLS
__atomic_store ((gint *)(atomic), &gais_temp, __ATOMIC_SEQ_CST); \
}))
+#if defined(g_has_typeof)
#define g_atomic_pointer_get(atomic) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
- gpointer gapg_temp; \
- __atomic_load ((gpointer *)(atomic), &gapg_temp, __ATOMIC_SEQ_CST); \
- gapg_temp; \
+ __typeof__(*(atomic)) gapg_temp_newval; \
+ __typeof__((atomic)) gapg_temp_atomic = (atomic); \
+ __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \
+ gapg_temp_newval; \
}))
#define g_atomic_pointer_set(atomic, newval) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
- gpointer gaps_temp = (gpointer)(newval); \
+ __typeof__((atomic)) gaps_temp_atomic = (atomic); \
+ __typeof__(*(atomic)) gaps_temp_newval = (newval); \
(void) (0 ? (gpointer) *(atomic) : NULL); \
- __atomic_store ((gpointer *)(atomic), &gaps_temp, __ATOMIC_SEQ_CST); \
+ __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
}))
+#else /* if !defined(g_has_typeof) */
+#define g_atomic_pointer_get(atomic) \
+ (G_GNUC_EXTENSION ({ \
+ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
+ gpointer gapg_temp_newval; \
+ gpointer *gapg_temp_atomic = (gpointer *)(atomic); \
+ __atomic_load (gapg_temp_atomic, &gapg_temp_newval, __ATOMIC_SEQ_CST); \
+ gapg_temp_newval; \
+ }))
+#define g_atomic_pointer_set(atomic, newval) \
+ (G_GNUC_EXTENSION ({ \
+ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
+ gpointer *gaps_temp_atomic = (gpointer *)(atomic); \
+ gpointer gaps_temp_newval = (gpointer)(newval); \
+ (void) (0 ? (gpointer) *(atomic) : NULL); \
+ __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \
+ }))
+#endif /* !defined(g_has_typeof) */
#else /* defined(__ATOMIC_SEQ_CST) */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]