Merge branch 'g-set-object-strict-aliasing' into 'master'

gobject: Fix strict aliasing warnings with g_set_object()

See merge request GNOME/glib!1372
This commit is contained in:
Sebastian Dröge 2020-02-18 13:25:31 +00:00
commit b947efb021
2 changed files with 49 additions and 0 deletions

View File

@ -738,12 +738,31 @@ static inline gboolean
return TRUE;
}
/* We need GCC for __extension__, which we need to sort out strict aliasing of @object_ptr */
#if defined(__GNUC__)
#define g_set_object(object_ptr, new_object) \
(G_GNUC_EXTENSION ({ \
G_STATIC_ASSERT (sizeof *(object_ptr) == sizeof (new_object)); \
/* Only one access, please; work around type aliasing */ \
union { char *in; GObject **out; } _object_ptr; \
_object_ptr.in = (char *) (object_ptr); \
/* Check types match */ \
(void) (0 ? *(object_ptr) = (new_object), FALSE : FALSE); \
(g_set_object) (_object_ptr.out, (GObject *) new_object); \
})) \
GLIB_AVAILABLE_MACRO_IN_2_44
#else /* if !defined(__GNUC__) */
#define g_set_object(object_ptr, new_object) \
(/* Check types match. */ \
0 ? *(object_ptr) = (new_object), FALSE : \
(g_set_object) ((GObject **) (object_ptr), (GObject *) (new_object)) \
)
#endif /* !defined(__GNUC__) */
/**
* g_assert_finalize_object: (skip)
* @object: (transfer full) (type GObject.Object): an object

View File

@ -217,6 +217,35 @@ test_set_function (void)
g_assert_null (tmp_weak);
}
static void
test_set_derived_type (void)
{
GBinding *obj = NULL;
GObject *o = NULL;
GBinding *b = NULL;
g_test_summary ("Check that g_set_object() doesnt give strict aliasing "
"warnings when used on types derived from GObject");
g_assert_false (g_set_object (&o, NULL));
g_assert_null (o);
g_assert_false (g_set_object (&b, NULL));
g_assert_null (b);
obj = g_object_new (my_object_get_type (), NULL);
g_assert_true (g_set_object (&o, G_OBJECT (obj)));
g_assert_true (o == G_OBJECT (obj));
g_assert_true (g_set_object (&b, obj));
g_assert_true (b == obj);
g_object_unref (obj);
g_clear_object (&b);
g_clear_object (&o);
}
static void
toggle_cb (gpointer data, GObject *obj, gboolean is_last)
{
@ -774,6 +803,7 @@ main (int argc, char **argv)
g_test_add_func ("/object/clear-function", test_clear_function);
g_test_add_func ("/object/set", test_set);
g_test_add_func ("/object/set-function", test_set_function);
g_test_add_func ("/object/set/derived-type", test_set_derived_type);
g_test_add_func ("/object/value", test_object_value);
g_test_add_func ("/object/initially-unowned", test_initially_unowned);
g_test_add_func ("/object/weak-pointer", test_weak_pointer);