[vala/staging] vala: Fix compatible/disposable check between structs and their subtypes



commit 0497eccfb1638da5b1acbe6c54dc659f7fb8b692
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Fri Oct 4 14:12:46 2019 +0200

    vala: Fix compatible/disposable check between structs and their subtypes
    
    This fixes memory leaks due to missing copy/destroy and improperly created
    dup functions and allows direct assignment between structs and their
    subtypes.
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/861

 tests/Makefile.am                    |  1 +
 tests/structs/struct-base-types.vala | 31 +++++++++++++++++++++++++++++++
 vala/valadatatype.vala               |  5 +++++
 vala/valastruct.vala                 |  7 +++++++
 4 files changed, 44 insertions(+)
---
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b404f7af3..011fefa1a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -221,6 +221,7 @@ TESTS = \
        enums/bug763831.vala \
        enums/bug780050.vala \
        structs/struct_only.vala \
+       structs/struct-base-types.vala \
        structs/struct-empty-still.test \
        structs/struct-no-gtype.vala \
        structs/struct-static-field-initializer.vala \
diff --git a/tests/structs/struct-base-types.vala b/tests/structs/struct-base-types.vala
new file mode 100644
index 000000000..928f010bb
--- /dev/null
+++ b/tests/structs/struct-base-types.vala
@@ -0,0 +1,31 @@
+struct Foo {
+       public string s;
+}
+
+struct Bar : Foo {
+}
+
+void main () {
+       {
+               Bar bar = { "bar" };
+               Foo foo = bar;
+
+               assert (bar.s == "bar");
+               assert (bar.s == foo.s);
+
+               void* s1 = foo.s;
+               void* s2 = bar.s;
+               assert (s1 != s2);
+       }
+       {
+               Foo foo = { "foo" };
+               Bar bar = foo;
+
+               assert (foo.s == "foo");
+               assert (foo.s == bar.s);
+
+               void* s1 = foo.s;
+               void* s2 = bar.s;
+               assert (s1 != s2);
+       }
+}
diff --git a/vala/valadatatype.vala b/vala/valadatatype.vala
index 6dc7cd07f..e968ec989 100644
--- a/vala/valadatatype.vala
+++ b/vala/valadatatype.vala
@@ -365,6 +365,11 @@ public abstract class Vala.DataType : CodeNode {
                                        return true;
                                }
                        }
+
+                       // Allow compatiblity of struct subtypes in both ways
+                       if (expect_struct.is_subtype_of (expr_struct)) {
+                               return true;
+                       }
                }
 
                return false;
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index f8b725fd8..9adb61bd2 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -215,6 +215,9 @@ public class Vala.Struct : TypeSymbol {
         * @return list of fields
         */
        public unowned List<Field> get_fields () {
+               if (base_struct != null) {
+                       return base_struct.get_fields ();
+               }
                return fields;
        }
 
@@ -447,6 +450,10 @@ public class Vala.Struct : TypeSymbol {
                        return true;
                }
 
+               if (base_struct != null) {
+                       return base_struct.is_disposable ();
+               }
+
                foreach (Field f in fields) {
                        if (f.binding == MemberBinding.INSTANCE
                            && f.get_attribute_bool ("CCode", "delegate_target", true)


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