atomic/tests: test g_atomic_pointer_compare_and_exchange() with const pointers

g_atomic_pointer_compare_and_exchange() should work with const pointers.
Add a test for that.

It seems clang 9.0.0-2.fc32 does not like this:

    ../glib/tests/atomic.c:93:9: warning: incompatible pointer types passing 'typeof ((((void *)0))) *' (aka 'void **') to parameter of type 'const char **' [-Wincompatible-pointer-types]
      res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, str);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../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; \
                                               ^~~~~~~~~~~~~~
    ../glib/tests/atomic.c:96:9: warning: incompatible pointer types passing 'typeof ((((void *)0))) *' (aka 'void **') to parameter of type 'const char **' [-Wincompatible-pointer-types]
      res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, str);
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ../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; \
                                               ^~~~~~~~~~~~~~

Note that this clang version already issues various compiler warnings for
this test. This merely adds another case to check.

Eventually g_atomic_pointer_compare_and_exchange() should be fixed to
avoid compiler warnings.

Actually there is a problem. When you try to use g_atomic_pointer_compare_and_exchange()
with const pointers, it is also not working, because the implementation
as a function expects "void *" arguments. As the test also shows. As such,
it's probably not portable to use g_atomic_pointer_compare_and_exchange()
with const pointers at all. However, the macro implementation is (with the right
compiler) fine with that, so it's an easy "mistake" to make.
This commit is contained in:
Thomas Haller 2019-12-13 13:57:42 +01:00
parent a8263add45
commit ef9ce8ea00

View File

@ -24,6 +24,9 @@ test_types (void)
guint u, u2;
gint s, s2;
gpointer vp, vp2;
const char *vp_str;
const char *volatile vp_str_vol;
const char *str = "Hello";
int *ip, *ip2;
gsize gs, gs2;
gboolean res;
@ -87,6 +90,14 @@ test_types (void)
g_assert_true (res);
g_assert_true (vp == 0);
g_atomic_pointer_set (&vp_str, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, str);
g_assert_true (res);
g_atomic_pointer_set (&vp_str_vol, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, str);
g_assert_true (res);
g_atomic_pointer_set (&ip, 0);
ip2 = g_atomic_pointer_get (&ip);
g_assert_true (ip2 == 0);
@ -195,6 +206,14 @@ G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (res);
g_assert_true (vp == 0);
g_atomic_pointer_set (&vp_str, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str, NULL, (char *) str);
g_assert_true (res);
g_atomic_pointer_set (&vp_str_vol, NULL);
res = g_atomic_pointer_compare_and_exchange (&vp_str_vol, NULL, (char *) str);
g_assert_true (res);
g_atomic_pointer_set (&ip, 0);
ip2 = g_atomic_pointer_get (&ip);
g_assert_true (ip2 == 0);