diff options
author | Philip Withnall <philip@tecnocode.co.uk> | 2020-10-15 08:52:47 +0000 |
---|---|---|
committer | Philip Withnall <philip@tecnocode.co.uk> | 2020-10-15 08:52:47 +0000 |
commit | e2e8339e0ac4f5a6a972af85c8a09e99c50a564b (patch) | |
tree | b8809c496d1d3e19ae1b8e30bbc2181727c0bbe2 | |
parent | 31bca17f52ee1170953bd166d4066a1a037b5d71 (diff) | |
parent | 0d81443ec025b832d3f072a25bdc8e74c13a3919 (diff) | |
download | glib-e2e8339e0ac4f5a6a972af85c8a09e99c50a564b.tar.gz |
Merge branch 'typeof' into 'master'
Use C++11 decltype where possible
See merge request GNOME/glib!1575
-rw-r--r-- | docs/reference/glib/glib-sections.txt | 2 | ||||
-rw-r--r-- | gio/gcredentials.c | 2 | ||||
-rw-r--r-- | glib/gatomic.h | 66 | ||||
-rw-r--r-- | glib/gmacros.h | 8 | ||||
-rw-r--r-- | glib/gmem.h | 26 | ||||
-rw-r--r-- | glib/grcbox.h | 18 | ||||
-rw-r--r-- | glib/tests/cxx.cpp | 64 | ||||
-rw-r--r-- | glib/tests/meson.build | 3 | ||||
-rw-r--r-- | gobject/gobject.h | 6 |
9 files changed, 145 insertions, 50 deletions
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index e96e6c86b..02bb2ba50 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -730,7 +730,7 @@ GLIB_UNAVAILABLE_TYPE G_ANALYZER_ANALYZING G_ANALYZER_NORETURN g_autoptr_cleanup_generic_gfree -g_has_typeof +glib_typeof g_macro__has_attribute g_macro__has_builtin g_macro__has_feature diff --git a/gio/gcredentials.c b/gio/gcredentials.c index 146829e7c..9423f9ef9 100644 --- a/gio/gcredentials.c +++ b/gio/gcredentials.c @@ -225,7 +225,7 @@ g_credentials_to_string (GCredentials *credentials) { GString *ret; #if G_CREDENTIALS_USE_APPLE_XUCRED - __typeof__(credentials->native.cr_ngroups) i; + glib_typeof (credentials->native.cr_ngroups) i; #endif g_return_val_if_fail (G_IS_CREDENTIALS (credentials), NULL); diff --git a/glib/gatomic.h b/glib/gatomic.h index 6bf41bb74..bb1435c70 100644 --- a/glib/gatomic.h +++ b/glib/gatomic.h @@ -103,24 +103,24 @@ 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)); \ - __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)); \ - __typeof__((atomic)) gaps_temp_atomic = (atomic); \ - __typeof__(*(atomic)) gaps_temp_newval = (newval); \ - (void) (0 ? (gpointer) *(atomic) : NULL); \ - __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \ - })) -#else /* if !defined(g_has_typeof) */ +#if defined(glib_typeof) +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + glib_typeof (*(atomic)) gapg_temp_newval; \ + glib_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)); \ + glib_typeof ((atomic)) gaps_temp_atomic = (atomic); \ + glib_typeof (*(atomic)) gaps_temp_newval = (newval); \ + (void) (0 ? (gpointer) * (atomic) : NULL); \ + __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \ + })) +#else /* if !defined(glib_typeof) */ #define g_atomic_pointer_get(atomic) \ (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ @@ -137,7 +137,7 @@ G_END_DECLS (void) (0 ? (gpointer) *(atomic) : NULL); \ __atomic_store (gaps_temp_atomic, &gaps_temp_newval, __ATOMIC_SEQ_CST); \ })) -#endif /* !defined(g_has_typeof) */ +#endif /* !defined(glib_typeof) */ #define g_atomic_int_inc(atomic) \ (G_GNUC_EXTENSION ({ \ @@ -183,14 +183,25 @@ G_END_DECLS (guint) __atomic_fetch_xor ((atomic), (val), __ATOMIC_SEQ_CST); \ })) +#if defined(glib_typeof) +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof (oldval) == sizeof (gpointer)); \ + glib_typeof ((oldval)) gapcae_oldval = (oldval); \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \ + })) +#else /* if !defined(glib_typeof) */ #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof (oldval) == sizeof (gpointer)); \ - __typeof__ ((oldval)) gapcae_oldval = (oldval); \ + gpointer gapcae_oldval = (gpointer)(oldval); \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ (void) (0 ? (gpointer) *(atomic) : NULL); \ __atomic_compare_exchange_n ((atomic), &gapcae_oldval, (newval), FALSE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? TRUE : FALSE; \ })) +#endif /* defined(glib_typeof) */ #define g_atomic_pointer_add(atomic, val) \ (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ @@ -283,14 +294,25 @@ G_END_DECLS __asm__ __volatile__ ("" : : : "memory"); \ gapg_result; \ })) +#if defined(glib_typeof) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : NULL); \ + __sync_synchronize (); \ + __asm__ __volatile__ ("" : : : "memory"); \ + *(atomic) = (glib_typeof (*(atomic))) (gsize) (newval); \ + })) +#else /* if !defined(glib_typeof) */ #define g_atomic_pointer_set(atomic, newval) \ (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ (void) (0 ? (gpointer) *(atomic) : NULL); \ __sync_synchronize (); \ __asm__ __volatile__ ("" : : : "memory"); \ - *(atomic) = (__typeof__ (*(atomic))) (gsize) (newval); \ + *(atomic) = (gpointer) (gsize) (newval); \ })) +#endif /* defined(glib_typeof) */ #define g_atomic_int_inc(atomic) \ (G_GNUC_EXTENSION ({ \ @@ -408,6 +430,6 @@ G_END_DECLS #define g_atomic_pointer_xor(atomic, val) \ (g_atomic_pointer_xor ((atomic), (gsize) (val))) -#endif /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */ +#endif /* defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) */ #endif /* __G_ATOMIC_H__ */ diff --git a/glib/gmacros.h b/glib/gmacros.h index d953de4c8..0dd9a41c2 100644 --- a/glib/gmacros.h +++ b/glib/gmacros.h @@ -231,9 +231,13 @@ * * This symbol is private. */ -#undef g_has_typeof +#undef glib_typeof #if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && !defined(__cplusplus) -#define g_has_typeof +#define glib_typeof(t) __typeof__ (t) +#elif defined(__cplusplus) && __cplusplus >= 201103L +/* C++11 decltype() is close enough for our usage */ +#include <type_traits> +#define glib_typeof(t) std::remove_reference<decltype (t)>::type #endif /* diff --git a/glib/gmem.h b/glib/gmem.h index 45671073b..924299b20 100644 --- a/glib/gmem.h +++ b/glib/gmem.h @@ -110,16 +110,18 @@ gpointer g_try_realloc_n (gpointer mem, gsize n_blocks, gsize n_block_bytes) G_GNUC_WARN_UNUSED_RESULT; -#if defined(g_has_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58 -#define g_clear_pointer(pp, destroy) \ - G_STMT_START { \ - G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \ - __typeof__((pp)) _pp = (pp); \ - __typeof__(*(pp)) _ptr = *_pp; \ - *_pp = NULL; \ - if (_ptr) \ - (destroy) (_ptr); \ - } G_STMT_END \ +#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58 +#define g_clear_pointer(pp, destroy) \ + G_STMT_START \ + { \ + G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \ + glib_typeof ((pp)) _pp = (pp); \ + glib_typeof (*(pp)) _ptr = *_pp; \ + *_pp = NULL; \ + if (_ptr) \ + (destroy) (_ptr); \ + } \ + G_STMT_END \ GLIB_AVAILABLE_MACRO_IN_2_34 #else /* __GNUC__ */ #define g_clear_pointer(pp, destroy) \ @@ -211,8 +213,8 @@ g_steal_pointer (gpointer pp) } /* type safety */ -#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && !defined(__cplusplus) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58 -#define g_steal_pointer(pp) ((__typeof__(*pp)) (g_steal_pointer) (pp)) +#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_58 +#define g_steal_pointer(pp) ((glib_typeof (*pp)) (g_steal_pointer) (pp)) #else /* __GNUC__ */ /* This version does not depend on gcc extensions, but gcc does not warn * about incompatible-pointer-types: */ diff --git a/glib/grcbox.h b/glib/grcbox.h index c92791260..f78f5cb3b 100644 --- a/glib/grcbox.h +++ b/glib/grcbox.h @@ -71,18 +71,18 @@ gsize g_atomic_rc_box_get_size (gpointer mem_block); #define g_atomic_rc_box_new0(type) \ ((type *) g_atomic_rc_box_alloc0 (sizeof (type))) -#ifdef g_has_typeof +#ifdef glib_typeof /* Type check to avoid assigning references to different types */ -# define g_rc_box_acquire(mem_block) \ - ((__typeof__(mem_block)) (g_rc_box_acquire) (mem_block)) -# define g_atomic_rc_box_acquire(mem_block) \ - ((__typeof__(mem_block)) (g_atomic_rc_box_acquire) (mem_block)) +#define g_rc_box_acquire(mem_block) \ + ((glib_typeof (mem_block)) (g_rc_box_acquire) (mem_block)) +#define g_atomic_rc_box_acquire(mem_block) \ + ((glib_typeof (mem_block)) (g_atomic_rc_box_acquire) (mem_block)) /* Type check to avoid duplicating data to different types */ -# define g_rc_box_dup(block_size,mem_block) \ - ((__typeof__(mem_block)) (g_rc_box_dup) (block_size,mem_block)) -# define g_atomic_rc_box_dup(block_size,mem_block) \ - ((__typeof__(mem_block)) (g_atomic_rc_box_dup) (block_size,mem_block)) +#define g_rc_box_dup(block_size, mem_block) \ + ((glib_typeof (mem_block)) (g_rc_box_dup) (block_size, mem_block)) +#define g_atomic_rc_box_dup(block_size, mem_block) \ + ((glib_typeof (mem_block)) (g_atomic_rc_box_dup) (block_size, mem_block)) #endif G_END_DECLS diff --git a/glib/tests/cxx.cpp b/glib/tests/cxx.cpp new file mode 100644 index 000000000..c423b2fbc --- /dev/null +++ b/glib/tests/cxx.cpp @@ -0,0 +1,64 @@ +/* + * Copyright 2020 Xavier Claessens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <glib.h> + +typedef struct +{ + int dummy; +} MyObject; + +static void +test_typeof (void) +{ +#if __cplusplus >= 201103L + // Test that with C++11 we don't get those kind of errors: + // error: invalid conversion from ‘gpointer’ {aka ‘void*’} to ‘MyObject*’ [-fpermissive] + MyObject *obj = g_rc_box_new0 (MyObject); + MyObject *obj2 = g_rc_box_acquire (obj); + g_assert_true (obj2 == obj); + + MyObject *obj3 = g_atomic_pointer_get (&obj2); + g_assert_true (obj3 == obj); + + MyObject *obj4 = nullptr; + g_atomic_pointer_set (&obj4, obj3); + g_assert_true (obj4 == obj); + + MyObject *obj5 = nullptr; + g_atomic_pointer_compare_and_exchange (&obj5, nullptr, obj4); + g_assert_true (obj5 == obj); + + MyObject *obj6 = g_steal_pointer (&obj5); + g_assert_true (obj6 == obj); + + g_clear_pointer (&obj6, g_rc_box_release); + g_rc_box_release (obj); +#else + g_test_skip ("This test requires C++11 compiler"); +#endif +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/C++/typeof", test_typeof); + + return g_test_run (); +} diff --git a/glib/tests/meson.build b/glib/tests/meson.build index 567f5eda4..1c78dbf08 100644 --- a/glib/tests/meson.build +++ b/glib/tests/meson.build @@ -14,6 +14,9 @@ glib_tests = { 'collate' : {}, 'cond' : {}, 'convert' : {}, + 'cxx' : { + 'source' : ['cxx.cpp'], + }, 'dataset' : {}, 'date' : {}, 'dir' : {}, diff --git a/gobject/gobject.h b/gobject/gobject.h index 499329af2..bf5496c54 100644 --- a/gobject/gobject.h +++ b/gobject/gobject.h @@ -513,10 +513,10 @@ GLIB_AVAILABLE_IN_ALL void g_object_remove_weak_pointer (GObject *object, gpointer *weak_pointer_location); -#if defined(g_has_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_56 +#if defined(glib_typeof) && GLIB_VERSION_MAX_ALLOWED >= GLIB_VERSION_2_56 /* Make reference APIs type safe with macros */ -#define g_object_ref(Obj) ((__typeof__(Obj)) (g_object_ref) (Obj)) -#define g_object_ref_sink(Obj) ((__typeof__(Obj)) (g_object_ref_sink) (Obj)) +#define g_object_ref(Obj) ((glib_typeof (Obj)) (g_object_ref) (Obj)) +#define g_object_ref_sink(Obj) ((glib_typeof (Obj)) (g_object_ref_sink) (Obj)) #endif /** |