summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2022-01-16 19:25:51 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2022-02-16 18:29:54 +0100
commit142f045f3681e2bad17eb1bd6bc6ec2fad2acfeb (patch)
treef8f416a227881875665335c559ff09b5b951d944
parent7ac7e059335caf671b21c462706faee97bd57f4d (diff)
downloadvala-142f045f3681e2bad17eb1bd6bc6ec2fad2acfeb.tar.gz
vala: Require lvalue access of delegate target/destroy "fields"
In addition to c054da918a40f8ef93c1a006034fb6ab4717c135 See https://gitlab.gnome.org/GNOME/vala/issues/857
-rw-r--r--codegen/valaccodememberaccessmodule.vala4
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/delegates/member-target-destroy-2.vala20
-rw-r--r--vala/valamemberaccess.vala8
4 files changed, 31 insertions, 2 deletions
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 7e052b6a1..ece18564c 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -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) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7d3859832..c3fad8451 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -427,6 +427,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
index 000000000..62ecd263a
--- /dev/null
+++ b/tests/delegates/member-target-destroy-2.vala
@@ -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);
+}
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 10c59d34c..e06cb1d14 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -1063,6 +1063,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) {