]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Don't carry floating reference into unknown target type expression
authorRico Tzschichholz <ricotz@ubuntu.com>
Fri, 26 Jun 2020 13:27:11 +0000 (15:27 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Tue, 30 Jun 2020 13:47:23 +0000 (15:47 +0200)
A floating reference result of a method, which may throw an error, needs
to be sinked when passed as argument for ellipsis parameter.

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

tests/Makefile.am
tests/semantic/floating-reference-error.vala [new file with mode: 0644]
tests/semantic/floating-reference.vala
vala/valamethodcall.vala

index 84508345e9ec9d584d0878fa993535d16ae0fbb5..a4ba93a1d6b4ebd4fc4e855f4a7f097666726dd3 100644 (file)
@@ -781,6 +781,7 @@ TESTS = \
        semantic/field-valist.test \
        semantic/field-void.test \
        semantic/floating-reference.vala \
+       semantic/floating-reference-error.vala \
        semantic/foreach-iterator-args.test \
        semantic/foreach-iterator-element-owned.test \
        semantic/foreach-iterator-void.test \
diff --git a/tests/semantic/floating-reference-error.vala b/tests/semantic/floating-reference-error.vala
new file mode 100644 (file)
index 0000000..37839d6
--- /dev/null
@@ -0,0 +1,22 @@
+[CCode (returns_floating_reference = true)]
+Variant? get_floating_variant_with_error () throws Error {
+       return new Variant.string ("bar");
+}
+
+void variant_args (int first, ...) {
+       var va = va_list ();
+       assert (!va.arg<Variant> ().is_floating ());
+}
+
+void main () {
+       {
+               variant_args (23, get_floating_variant_with_error ());
+       }
+       {
+               try {
+                       variant_args (42, get_floating_variant_with_error ());
+               } catch {
+                       assert_not_reached ();
+               }
+       }
+}
index f690d690ddc7504a91661e5fb0d2b45b4a903d3f..3cba748650a7810445b230c8f957840843da4674 100644 (file)
@@ -3,6 +3,11 @@ Variant get_floating_variant () {
        return new Variant.string ("foo");
 }
 
+[CCode (returns_floating_reference = true)]
+Variant? get_floating_variant_with_error () throws Error {
+       return new Variant.string ("bar");
+}
+
 void test_variant () {
        {
                string? @value = "bar";
@@ -45,6 +50,18 @@ void test_variant () {
                Variant? variant = get_floating_variant ();
                assert (!variant.is_floating ());
        }
+       {
+               Variant? variant = get_floating_variant_with_error ();
+               assert (!variant.is_floating ());
+       }
+       {
+               try {
+                       Variant? variant = get_floating_variant_with_error ();
+                       assert (!variant.is_floating ());
+               } catch {
+                       assert_not_reached ();
+               }
+       }
 }
 
 void test_variant_builder () {
index f71eb957ca681f320b99d57879f26eeb34e2f335..a1782217a06696ad1b4dca422d19b49c0ea2dbfd 100644 (file)
@@ -669,6 +669,11 @@ public class Vala.MethodCall : Expression {
                                var local = new LocalVariable (value_type.copy (), get_temp_name (), null, source_reference);
                                var decl = new DeclarationStatement (local, source_reference);
 
+                               // don't carry floating reference any further if the target-type is unknown
+                               if (target_type == null) {
+                                       local.variable_type.floating_reference = false;
+                               }
+
                                insert_statement (context.analyzer.insert_block, decl);
 
                                var temp_access = SemanticAnalyzer.create_temp_access (local, target_type);