]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Handle delegate_target attribute of fields
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 30 May 2018 15:02:42 +0000 (17:02 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Thu, 31 May 2018 11:14:00 +0000 (13:14 +0200)
Delegate fields without a delegate target don't require special handling
on copy/destroy.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/520

codegen/valaccodeassignmentmodule.vala
codegen/valaccodebasemodule.vala
codegen/valaccodestructmodule.vala
codegen/valagtypemodule.vala
tests/Makefile.am
tests/delegates/fields-no-target.vala [new file with mode: 0644]
vala/valastruct.vala

index 6e9ce0dd15b36fcd84d3e32110e5a07a2a850d9f..c8f24383ee9673caf41c23cb40da89ad7f1cdbde 100644 (file)
@@ -221,7 +221,7 @@ public class Vala.CCodeAssignmentModule : CCodeMemberAccessModule {
                if (lvalue.actual_value_type != null) {
                        type = lvalue.actual_value_type;
                }
-               if (requires_destroy (type)) {
+               if (get_ccode_delegate_target (field) && requires_destroy (type)) {
                        /* unref old value */
                        ccode.add_expression (destroy_field (field, instance));
                }
index 4c1e60685c666c59f51408f8515dd6c3df56b033..9147a5fa00f9f8278fbc8362af7eb43e0a3b35f3 100644 (file)
@@ -1084,7 +1084,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        decl_space.add_type_member_declaration (cdecl);
                                }
                        }
-               } else if (f.variable_type is DelegateType) {
+               } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                        var delegate_type = (DelegateType) f.variable_type;
                        if (delegate_type.delegate_symbol.has_target) {
                                // create field to store delegate target
@@ -1172,7 +1172,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                        var rhs_array_len = get_array_length_cvalue (field_value, 1);
                                                        ccode.add_assignment (lhs_array_size, rhs_array_len);
                                                }
-                                       } else if (f.variable_type is DelegateType) {
+                                       } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                                var delegate_type = (DelegateType) f.variable_type;
                                                if (delegate_type.delegate_symbol.has_target) {
                                                        var field_value = get_field_cvalue (f, load_this_parameter ((TypeSymbol) f.parent_symbol));
@@ -1194,7 +1194,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                pop_context ();
                        }
 
-                       if (requires_destroy (f.variable_type) && instance_finalize_context != null) {
+                       if (get_ccode_delegate_target (f) && requires_destroy (f.variable_type) && instance_finalize_context != null) {
                                push_context (instance_finalize_context);
                                ccode.add_expression (destroy_field (f, load_this_parameter ((TypeSymbol) f.parent_symbol)));
                                pop_context ();
@@ -1304,7 +1304,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                                        cfile.add_type_member_declaration (cdecl);
                                                }
                                        }
-                               } else if (f.variable_type is DelegateType) {
+                               } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                        var delegate_type = (DelegateType) f.variable_type;
                                        if (delegate_type.delegate_symbol.has_target) {
                                                // create field to store delegate target
@@ -6376,7 +6376,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                var this_value = load_this_parameter (st);
                foreach (Field f in st.get_fields ()) {
                        if (f.binding == MemberBinding.INSTANCE) {
-                               if (requires_destroy (f.variable_type)) {
+                               if (get_ccode_delegate_target (f) && requires_destroy (f.variable_type)) {
                                        ccode.add_expression (destroy_field (f, this_value));
                                }
                        }
@@ -6407,7 +6407,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                foreach (Field f in st.get_fields ()) {
                        if (f.binding == MemberBinding.INSTANCE) {
                                var value = load_field (f, load_this_parameter ((TypeSymbol) st));
-                               if (requires_copy (f.variable_type))  {
+                               if (get_ccode_delegate_target (f) && requires_copy (f.variable_type))  {
                                        value = copy_value (value, f);
                                        if (value == null) {
                                                // error case, continue to avoid critical
index 7b20f504a1da7af0ef107f383ec986ee6133e882..d9237e656f49f4c30bfed59b72b2eaec19f8363e 100644 (file)
@@ -95,7 +95,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
                                                        instance_struct.add_field (get_ccode_name (len_type), get_array_size_cname (get_ccode_name (f)));
                                                }
                                        }
-                               } else if (f.variable_type is DelegateType) {
+                               } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                        var delegate_type = (DelegateType) f.variable_type;
                                        if (delegate_type.delegate_symbol.has_target) {
                                                // create field to store delegate target
@@ -301,7 +301,7 @@ public abstract class Vala.CCodeStructModule : CCodeBaseModule {
                foreach (var f in st.get_fields ()) {
                        if (f.binding == MemberBinding.INSTANCE) {
                                var value = load_field (f, load_this_parameter ((TypeSymbol) st));
-                               if (requires_copy (f.variable_type))  {
+                               if (get_ccode_delegate_target (f) && requires_copy (f.variable_type))  {
                                        value = copy_value (value, f);
                                        if (value == null) {
                                                // error case, continue to avoid critical
index abb19f664b83dd6e3580bb2d18ac4a27ba9a2a4f..3d977784dc2011da31e99f938af51eac1392da26 100644 (file)
@@ -413,7 +413,7 @@ public class Vala.GTypeModule : GErrorModule {
                                                instance_struct.add_field (get_ccode_name (len_type), get_array_size_cname (get_ccode_name (f)));
                                        }
                                }
-                       } else if (f.variable_type is DelegateType) {
+                       } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                var delegate_type = (DelegateType) f.variable_type;
                                if (delegate_type.delegate_symbol.has_target) {
                                        // create field to store delegate target
@@ -514,7 +514,7 @@ public class Vala.GTypeModule : GErrorModule {
                                                                instance_priv_struct.add_field (get_ccode_name (len_type), get_array_size_cname (get_ccode_name (f)));
                                                        }
                                                }
-                                       } else if (f.variable_type is DelegateType) {
+                                       } else if (f.variable_type is DelegateType && get_ccode_delegate_target (f)) {
                                                var delegate_type = (DelegateType) f.variable_type;
                                                if (delegate_type.delegate_symbol.has_target) {
                                                        // create field to store delegate target
index aec6e33f2c2320957f9c397a29455a0ded68cb98..c05a68d51ecfe93021ef1cde228ff2c8aa521bef 100644 (file)
@@ -208,6 +208,7 @@ TESTS = \
        delegates/delegates.vala \
        delegates/delegates-error.test \
        delegates/fields.vala \
+       delegates/fields-no-target.vala \
        delegates/reference_transfer.vala \
        delegates/wrapper.vala \
        delegates/bug519949.test \
diff --git a/tests/delegates/fields-no-target.vala b/tests/delegates/fields-no-target.vala
new file mode 100644 (file)
index 0000000..ad328de
--- /dev/null
@@ -0,0 +1,39 @@
+public delegate void FooFunc ();
+
+[CCode (delegate_target = false)]
+public FooFunc func;
+
+public struct Foo {
+       [CCode (delegate_target = false)]
+       public FooFunc func;
+       public int i;
+}
+
+public class Bar {
+       [CCode (delegate_target = false)]
+       public FooFunc func;
+       public int i;
+}
+
+void foo_cb () {
+}
+
+const Foo[] foos = {
+       { foo_cb, 42 }
+};
+
+void main() {
+       func = foo_cb;
+
+       Foo f_stack = { foo_cb, 23 };
+       Foo? f_heap = { foo_cb, 4711 };
+
+       assert (f_stack.i == 23);
+       assert (f_heap.i == 4711);
+       assert (foos[0].i == 42);
+
+       Bar b = new Bar ();
+       b.func = foo_cb;
+       b.i = 42;
+}
+
index bca78510a668028a321ff660988f90266c37aa1b..1c4ba768cfd15af14dc02aa9933930f66325d8c0 100644 (file)
@@ -449,6 +449,7 @@ public class Vala.Struct : TypeSymbol {
 
                foreach (Field f in fields) {
                        if (f.binding == MemberBinding.INSTANCE
+                           && f.get_attribute_bool ("CCode", "delegate_target", true)
                            && f.variable_type.is_disposable ()) {
                                return true;
                        }