diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2022-01-16 19:25:51 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2022-02-16 18:29:54 +0100 |
commit | 142f045f3681e2bad17eb1bd6bc6ec2fad2acfeb (patch) | |
tree | f8f416a227881875665335c559ff09b5b951d944 | |
parent | 7ac7e059335caf671b21c462706faee97bd57f4d (diff) | |
download | vala-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.vala | 4 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/delegates/member-target-destroy-2.vala | 20 | ||||
-rw-r--r-- | vala/valamemberaccess.vala | 8 |
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) { |