]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: No-accessor struct properties in GLib.Object class must be owned a6441ec3c27e059d32501a4e09c937ac668f3ad9
authorRico Tzschichholz <ricotz@ubuntu.com>
Thu, 9 May 2019 08:17:36 +0000 (10:17 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 16 May 2019 19:17:36 +0000 (21:17 +0200)
Real structs are returned as heap-allocated structor by g_object_get() and
not defining them with owned getter results in memory leaks.

Additionally force DelegateType, PointerType and ValueType as unowned to
preserve the current behaviour for binding generation.

tests/Makefile.am
tests/objects/property-real-struct-no-accessor.test [new file with mode: 0644]
vala/valapropertyaccessor.vala

index 4527506aa484b33e6b9c8f592d4f851a4af627ad..57e784b61c27cadb7fe3ac6a200324f624627fa6 100644 (file)
@@ -317,6 +317,7 @@ TESTS = \
        objects/property-construct-only-write.test \
        objects/property-construct-only-write-foreign.test \
        objects/property-gboxed-nullable.vala \
+       objects/property-real-struct-no-accessor.test \
        objects/property-static.vala \
        objects/regex.vala \
        objects/signals.vala \
diff --git a/tests/objects/property-real-struct-no-accessor.test b/tests/objects/property-real-struct-no-accessor.test
new file mode 100644 (file)
index 0000000..c2c956b
--- /dev/null
@@ -0,0 +1,13 @@
+Invalid Code
+
+struct Foo {
+       public int i;
+}
+
+class Bar : Object {
+       [NoAccessorMethod]
+       public Foo foo { get; set; }
+}
+
+void main () {
+}
index f9fc981713e3244d8499ce05aa73c4746c43c27f..3c826737b7927687cde3c0a656ae37b390da75bf 100644 (file)
@@ -158,6 +158,23 @@ public class Vala.PropertyAccessor : Subroutine {
                        value_parameter = new Parameter ("value", value_type, source_reference);
                }
 
+               if (readable && ((TypeSymbol) prop.parent_symbol).is_subtype_of (context.analyzer.object_type)) {
+                       //FIXME Code duplication with CCodeMemberAccessModule.visit_member_access()
+                       if (prop.get_attribute ("NoAccessorMethod") != null) {
+                               if (value_type.is_real_struct_type ()) {
+                                       if (source_reference == null || source_reference.file == null) {
+                                               // Hopefully good as is
+                                       } else if (!value_type.value_owned && source_reference.file.file_type == SourceFileType.SOURCE) {
+                                               Report.error (source_reference, "unowned return value for getter of property `%s' not supported without accessor".printf (prop.get_full_name ()));
+                                       }
+                               } else if (value_type.value_owned && (source_reference == null || source_reference.file == null)) {
+                                       if (value_type is DelegateType || value_type is PointerType || (value_type is ValueType && !value_type.nullable)) {
+                                               value_type.value_owned = false;
+                                       }
+                               }
+                       }
+               }
+
                if (prop.source_type == SourceFileType.SOURCE) {
                        if (body == null && !prop.interface_only && !prop.is_abstract) {
                                /* no accessor body specified, insert default body */