]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Unowned delegates can't become owned when captured or in coroutine
authorLuca Bruno <lucabru@src.gnome.org>
Sun, 8 May 2011 06:32:14 +0000 (08:32 +0200)
committerLuca Bruno <lucabru@src.gnome.org>
Sun, 8 May 2011 06:55:03 +0000 (08:55 +0200)
From a semantic view point it's neither possible to transfer ownership
to an unowned delegate nor destroy its target.

codegen/valaccodememberaccessmodule.vala

index fb8ed3529f77748f2a1a60f5715d37de4cdea906..a6ab4d6aa6aac727334ef3a230b7f1b89091e4fa 100644 (file)
@@ -398,13 +398,15 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                if (param.has_array_length_cexpr) {
                        result.array_length_cexpr = new CCodeConstant (param.get_array_length_cexpr ());
                }
-               if (param.captured || is_in_coroutine ()) {
-                       result.value_type.value_owned = true;
-               }
 
                var array_type = result.value_type as ArrayType;
                var delegate_type = result.value_type as DelegateType;
 
+               bool is_unowned_delegate = delegate_type != null && !param.variable_type.value_owned;
+               if ((param.captured || is_in_coroutine ()) && !is_unowned_delegate) {
+                       result.value_type.value_owned = true;
+               }
+
                if (param.name == "this") {
                        if (is_in_coroutine ()) {
                                // use closure
@@ -433,7 +435,9 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
                                        }
                                } else if (delegate_type != null && delegate_type.delegate_symbol.has_target) {
                                        result.delegate_target_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_cname (get_variable_cname (param.name)));
-                                       result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
+                                       if (result.value_type.value_owned) {
+                                               result.delegate_target_destroy_notify_cvalue = new CCodeMemberAccess.pointer (get_variable_cexpression ("_data%d_".printf (get_block_id (block))), get_delegate_target_destroy_notify_cname (get_variable_cname (param.name)));
+                                       }
                                }
                        } else if (is_in_coroutine ()) {
                                // use closure