]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Always assign original variable when consuming instance to destroy
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 8 Apr 2019 08:00:19 +0000 (10:00 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 10 Apr 2019 14:26:19 +0000 (16:26 +0200)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/781

codegen/valaccodebasemodule.vala
tests/objects/compact-class-destructor.vala
vala/valamemberaccess.vala

index e0cc783c272aa9dbec5317fbe8e7a402b782821e..86c79b64e5be73db67b4396ef6afde9f42896655 100644 (file)
@@ -4050,15 +4050,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        if (expr.value_type != null) {
                                // FIXME: temporary workaround until the refactoring is complete, not all target_value have a value_type
                                expr.target_value.value_type = expr.value_type;
-
-                               if (is_compact_class_destructor_call (expr)) {
-                                       // transfer ownership here and consume given instance
-                                       var temp_value = store_temp_value (expr.target_value, expr);
-                                       ccode.add_assignment (get_cvalue (expr), new CCodeConstant ("NULL"));
-                                       expr.target_value = temp_value;
-                               } else {
-                                       expr.target_value = transform_value (expr.target_value, expr.target_type, expr);
-                               }
+                               expr.target_value = transform_value (expr.target_value, expr.target_type, expr);
                        }
 
                        if (expr.target_value == null) {
@@ -4076,6 +4068,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        if (!(expr.value_type is ValueType && !expr.value_type.nullable)) {
                                ((GLibValue) expr.target_value).non_null = expr.is_non_null ();
                        }
+               } else if (expr.value_type != null && is_compact_class_destructor_call (expr)) {
+                       // transfer ownership here and consume given instance
+                       var temp_value = store_temp_value (expr.target_value, expr);
+                       ccode.add_assignment (get_cvalue (expr), new CCodeConstant ("NULL"));
+                       expr.target_value = temp_value;
                }
        }
 
index 2d6d8a442c0007aecb86535aa83fd4358b775fbb..7aa4604b0924ea04227e71434a740bbd3889971c 100644 (file)
@@ -9,9 +9,90 @@ class Foo {
        }
 }
 
-void main () {
+void bar () throws Error {
+}
+
+Foo get_foo () {
+       return new Foo ();
+}
+
+class Bar {
+       Foo faz;
+
+       public void instance_simple () {
+               var foo = new Foo ();
+               var res = foo.destroy ();
+
+               assert (foo == null);
+               assert (res == 42);
+       }
+
+       public void instance_field () {
+               bar ();
+
+               faz = new Foo ();
+               var res = faz.destroy ();
+
+               assert (faz == null);
+               assert (res == 42);
+       }
+}
+
+Foo faz;
+
+void field () {
+       bar ();
+
+       faz = new Foo ();
+       var res = faz.destroy ();
+
+       assert (faz == null);
+       assert (res == 42);
+}
+
+void local () {
+       bar ();
+
        var foo = new Foo ();
        var res = foo.destroy ();
+
        assert (foo == null);
        assert (res == 42);
 }
+
+void parameter (owned Foo foo) {
+       bar ();
+
+       var res = foo.destroy ();
+
+       assert (foo == null);
+       assert (res == 42);
+}
+
+void simple () {
+       var foo = new Foo ();
+       var res = foo.destroy ();
+
+       assert (foo == null);
+       assert (res == 42);
+}
+
+void returned () {
+       bar ();
+
+       var res = get_foo ().destroy ();
+
+       assert (res == 42);
+}
+
+void main () {
+       simple ();
+       field ();
+       local ();
+       parameter (new Foo ());
+       returned ();
+
+       var bar = new Bar ();
+       bar.instance_simple ();
+       bar.instance_field ();
+}
index e07e1ec3f4d6e70ec7badcc656f3f6f99ebd0891..b7efcebbbd707e1ffe0473018a277c2531f0d934 100644 (file)
@@ -902,6 +902,13 @@ public class Vala.MemberAccess : Expression {
                                ma.check_lvalue_access ();
                        }
                }
+
+               if (symbol_reference is Method && ((Method) symbol_reference).get_attribute ("DestroysInstance") != null) {
+                       if (ma != null) {
+                               ma.lvalue = true;
+                               ma.check_lvalue_access ();
+                       }
+               }
        }
 
        public override void emit (CodeGenerator codegen) {