gobject: loosen property override flag restrictions
authorRyan Lortie <desrt@desrt.ca>
Tue, 20 Dec 2011 19:36:29 +0000 (14:36 -0500)
committerRyan Lortie <desrt@desrt.ca>
Tue, 20 Dec 2011 19:58:38 +0000 (14:58 -0500)
GObject enforces the following restrictions on property overrides:

  - must only add abilities: if the parent class supports
    readability/writability then the subclass must also support them.
    Subclasses are free to add readability/writability.

  - must not add additional restrictions: if the parent class doesn't
    have construct/construct-only restrictions then the subclass must
    not add them.  Subclasses are free to remove restrictions.

The problem with the previous implementation is that the check against
adding construct/construct-only restrictions was being done even if the
property was not previously writable.  As an example:

  "readable" and "writable only on construct"

was considered as being more restrictive than

  "read only".

This patch tweaks the check to allow the addition of
construct/construct-only restrictions for properties that were
previously read-only and are now being made writable.

https://bugzilla.gnome.org/show_bug.cgi?id=666615

gobject/gobject.c

index 166faac..59fcca2 100644 (file)
@@ -1396,14 +1396,15 @@ object_interface_check_properties (gpointer func_data,
 
 #define SUBSET(a,b,mask) (((a) & ~(b) & (mask)) == 0)
 
-      /* CONSTRUCT and CONSTRUCT_ONLY add restrictions.
+      /* CONSTRUCT and CONSTRUCT_ONLY add restrictions to writability.
        * READABLE and WRITABLE remove restrictions. The implementation
        * paramspec must have less restrictive flags.
        */
       if (class_pspec &&
-         (!SUBSET (class_pspec->flags,
-                   pspecs[n]->flags,
-                   G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY) ||
+          (((pspecs[n]->flags & G_PARAM_WRITABLE) &&
+            !SUBSET (class_pspec->flags,
+                     pspecs[n]->flags,
+                     G_PARAM_CONSTRUCT | G_PARAM_CONSTRUCT_ONLY)) ||
           !SUBSET (pspecs[n]->flags,
                    class_pspec->flags,
                    G_PARAM_READABLE | G_PARAM_WRITABLE)))