[glib] gobject: add type propagation to gobject ref API



commit 3fae39a5d742afe73741f5fd7aa24e3ae8182f06
Author: Christian Hergert <chergert redhat com>
Date:   Wed Nov 22 15:10:38 2017 -0800

    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 99f6ec9..d03d39f 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 b97dfb2..15f3529 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()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]