]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Check for matching ownership of type-arguments 4f5a770f20c0d13a0bee6e02af20a458aa378b1c 27/head
authorRico Tzschichholz <ricotz@ubuntu.com>
Thu, 5 Apr 2018 06:22:25 +0000 (08:22 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 7 Nov 2018 15:27:44 +0000 (16:27 +0100)
Non-boxed simple types can't be unowned and are therefore ignored.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/696

tests/Makefile.am
tests/semantic/type-argument-ownership-mismatch.test [new file with mode: 0644]
vala/valadatatype.vala

index fd0d2467567b6b046ecd4213d92cba3c5526eb85..8002849423046445d6df38922a5458fd5d84a000 100644 (file)
@@ -619,6 +619,7 @@ TESTS = \
        semantic/struct-field-initializer.test \
        semantic/struct-invalid-base.test \
        semantic/struct-recursive.test \
+       semantic/type-argument-ownership-mismatch.test \
        semantic/yield-call-requires-async-context.test \
        semantic/yield-call-requires-async-method.test \
        semantic/yield-creation-requires-async-context.test \
diff --git a/tests/semantic/type-argument-ownership-mismatch.test b/tests/semantic/type-argument-ownership-mismatch.test
new file mode 100644 (file)
index 0000000..a4dd9cb
--- /dev/null
@@ -0,0 +1,11 @@
+Invalid Code
+
+class Foo<T> {
+}
+
+Foo<string> foo () {
+       return new Foo<unowned string> ();
+}
+
+void main () {
+}
index 8c52a4bfa467bad918fe9c5823ff7d1f9b39a845..1e2f2c4cfc0a65b4eaa5ff367e9eeb1936339ac3 100644 (file)
@@ -305,11 +305,25 @@ public abstract class Vala.DataType : CodeNode {
                        return true;
                }
 
+               // check for matching ownership of type-arguments
+               var type_args = get_type_arguments ();
+               var target_type_args = target_type.get_type_arguments ();
+               if (type_args.size == target_type_args.size) {
+                       for (int i = 0; i < type_args.size; i++) {
+                               var type_arg = type_args[i];
+                               var target_type_arg = target_type_args[i];
+                               // Ignore non-boxed simple-type structs
+                               if (!type_arg.is_non_null_simple_type ()
+                                   && type_arg.is_weak () != target_type_arg.is_weak ()) {
+                                       return false;
+                               }
+                       }
+               }
+
                if (data_type != null && target_type.data_type != null && data_type.is_subtype_of (target_type.data_type)) {
                        var base_type = SemanticAnalyzer.get_instance_base_type_for_member(this, target_type.data_type, this);
                        // check compatibility of generic type arguments
                        var base_type_args = base_type.get_type_arguments();
-                       var target_type_args = target_type.get_type_arguments();
                        if (base_type_args.size == target_type_args.size) {
                                for (int i = 0; i < base_type_args.size; i++) {
                                        // mutable generic types require type argument equality,
@@ -418,6 +432,14 @@ public abstract class Vala.DataType : CodeNode {
                return is_real_struct_type () && !nullable;
        }
 
+       bool is_non_null_simple_type () {
+               unowned Struct s = data_type as Struct;
+               if (s != null && s.is_simple_type ()) {
+                       return !nullable;
+               }
+               return false;
+       }
+
        /**
         * Returns whether the value needs to be disposed, i.e. whether
         * allocated memory or other resources need to be released when