]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Require lvalue access of delegate target/destroy "fields"
authorRico Tzschichholz <ricotz@ubuntu.com>
Sun, 16 Jan 2022 18:25:51 +0000 (19:25 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 9 Feb 2022 21:16:44 +0000 (22:16 +0100)
In addition to c054da918a40f8ef93c1a006034fb6ab4717c135

See https://gitlab.gnome.org/GNOME/vala/issues/857

codegen/valaccodememberaccessmodule.vala
tests/Makefile.am
tests/delegates/member-target-destroy-2.vala [new file with mode: 0644]
vala/valamemberaccess.vala

index 455827b26d7b3cd4e2df868671f3f2d40ff5bb32..fa412ae5f3f5354bf2c4feda4b493d8d44e29957 100644 (file)
@@ -140,14 +140,14 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                Report.error (expr.source_reference, "unsupported use of target field of delegate without target");
                        }
                        CCodeExpression delegate_target_destroy_notify;
-                       set_cvalue (expr, get_delegate_target_cexpression (expr.inner, out delegate_target_destroy_notify));
+                       set_cvalue (expr, get_delegate_target_cexpression (expr.inner, out delegate_target_destroy_notify) ?? new CCodeConstant ("NULL"));
                } else if (expr.symbol_reference is DelegateDestroyField) {
                        if (!((DelegateType) expr.inner.value_type).delegate_symbol.has_target) {
                                Report.error (expr.source_reference, "unsupported use of destroy field of delegate without target");
                        }
                        CCodeExpression delegate_target_destroy_notify;
                        get_delegate_target_cexpression (expr.inner, out delegate_target_destroy_notify);
-                       set_cvalue (expr, delegate_target_destroy_notify);
+                       set_cvalue (expr, delegate_target_destroy_notify ?? new CCodeConstant ("NULL"));
                } else if (expr.symbol_reference is GenericDupField) {
                        set_cvalue (expr, get_dup_func_expression (expr.inner.value_type, expr.source_reference));
                } else if (expr.symbol_reference is GenericDestroyField) {
index c3f6dc6137b650c374c5fba9355d79d1a610fcdd..f68930da6efe6e923396415bc5e60603081e4b47 100644 (file)
@@ -431,6 +431,7 @@ TESTS = \
        delegates/lambda-outer-constant.test \
        delegates/lambda-shared-closure.vala \
        delegates/member-target-destroy.vala \
+       delegates/member-target-destroy-2.vala \
        delegates/reference_transfer.vala \
        delegates/return-array-null-terminated.vala \
        delegates/wrapper.vala \
diff --git a/tests/delegates/member-target-destroy-2.vala b/tests/delegates/member-target-destroy-2.vala
new file mode 100644 (file)
index 0000000..62ecd26
--- /dev/null
@@ -0,0 +1,20 @@
+delegate void FooFunc ();
+
+void bar (string s) {
+       assert (s == "foo");
+}
+
+void foo (owned FooFunc func) {
+       assert (func.target == "foo");
+       assert (func.destroy == g_free);
+       func ();
+}
+
+void main () {
+       FooFunc func = (FooFunc) bar;
+
+       func.target = "foo".dup ();
+       func.destroy = g_free;
+
+       foo ((owned) func);
+}
index b68676e444664a9961745fe202b92ff5244131b4..5f90a8449976b3118740406e188d3e0cc17cb3f3 100644 (file)
@@ -1093,6 +1093,14 @@ public class Vala.MemberAccess : Expression {
                        }
                }
 
+               if (symbol_reference is DelegateTargetField || symbol_reference is DelegateDestroyField) {
+                       inner.lvalue = true;
+                       if (ma != null) {
+                               ma.lvalue = true;
+                               ma.check_lvalue_access ();
+                       }
+               }
+
                if (symbol_reference is Method && ((Method) symbol_reference).get_attribute ("DestroysInstance") != null) {
                        unowned Class? cl = ((Method) symbol_reference).parent_symbol as Class;
                        if (cl != null && cl.is_compact && ma != null) {