From 3fae39a5d742afe73741f5fd7aa24e3ae8182f06 Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 22 Nov 2017 15:10:38 -0800 Subject: [PATCH] gobject: add type propagation to gobject ref API Currently, g_object_ref() and g_object_ref_sink() return a gpointer which can mask issues when assigning to fields or returning from a function. To help catch these type of programming errors, we can propagate the type of the parameter through the function call on GCC using the typeof() C language extension. This will cause offending code to have a warning, but will continue to be source and binary compatible. This is only enabled when GLIB_VERSION_MAX_ALLOWED is 2.56 or greater. https://bugzilla.gnome.org/show_bug.cgi?id=790697 --- gobject/gobject.c | 12 ++++++++++-- gobject/gobject.h | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gobject/gobject.c b/gobject/gobject.c index 99f6ec998..d03d39fe2 100644 --- a/gobject/gobject.c +++ b/gobject/gobject.c @@ -2980,12 +2980,15 @@ g_object_is_floating (gpointer _object) * count unchanged. If the object is not floating, then this call * adds a new normal reference increasing the reference count by one. * + * Since GLib 2.56, the type of @object will be propagated to the return type + * under the same conditions as for g_object_ref(). + * * Since: 2.10 * * Returns: (type GObject.Object) (transfer none): @object */ gpointer -g_object_ref_sink (gpointer _object) +(g_object_ref_sink) (gpointer _object) { GObject *object = _object; gboolean was_floating; @@ -3185,10 +3188,15 @@ g_object_remove_toggle_ref (GObject *object, * * Increases the reference count of @object. * + * Since GLib 2.56, if `GLIB_VERSION_MAX_ALLOWED` is 2.56 or greater, the type + * of @object will be propagated to the return type (using the GCC typeof() + * extension), so any casting the caller needs to do on the return type must be + * explicit. + * * Returns: (type GObject.Object) (transfer none): the same @object */ gpointer -g_object_ref (gpointer _object) +(g_object_ref) (gpointer _object) { GObject *object = _object; gint old_val; diff --git a/gobject/gobject.h b/gobject/gobject.h index b97dfb278..15f3529b9 100644 --- a/gobject/gobject.h +++ b/gobject/gobject.h @@ -508,6 +508,12 @@ GLIB_AVAILABLE_IN_ALL void g_object_remove_weak_pointer (GObject *object, gpointer *weak_pointer_location); +#if defined(__GNUC__) && 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)) +#endif + /** * GToggleNotify: * @data: Callback data passed to g_object_add_toggle_ref()