]> 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>
Fri, 26 Jun 2020 13:27:11 +0000 (15:27 +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 02af2fd5943dc15c69a0ef0eec8b0026f78ea7af..35b610d2ab45e703cb09869d72e51717b531e88d 100644 (file)
@@ -821,6 +821,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 3573113c4d2ec0646b086a7b6aad94799c4c20b5..baf704f450563800de4d5cb36a7c914ad3821057 100644 (file)
@@ -664,6 +664,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);