diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2018-05-30 17:02:42 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2018-05-31 13:14:00 +0200 |
commit | 0efcee2892c805d15fe46d4c9197669a0c51ad5f (patch) | |
tree | aceb3f7921d26594c21199216bc41623811f3a5a | |
parent | 72fab93ba9a5027fbdd30cabfa5cd32482dad07f (diff) | |
download | vala-0efcee2892c805d15fe46d4c9197669a0c51ad5f.tar.gz |
codegen: Handle delegate_target attribute of fields
Delegate fields without a delegate target don't require special handling
on copy/destroy.
Fixes https://gitlab.gnome.org/GNOME/vala/issues/520
-rw-r--r-- | codegen/valaccodeassignmentmodule.vala | 2 | ||||
-rw-r--r-- | codegen/valaccodebasemodule.vala | 12 | ||||
-rw-r--r-- | codegen/valaccodestructmodule.vala | 4 | ||||
-rw-r--r-- | codegen/valagtypemodule.vala | 4 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/delegates/fields-no-target.vala | 39 | ||||
-rw-r--r-- | vala/valastruct.vala | 1 |
7 files changed, 52 insertions, 11 deletions
diff --git a/codegen/valaccodeassignmentmodule.vala b/codegen/valaccodeassignmentmodule.vala index 6e9ce0dd1..c8f24383e 100644 --- a/codegen/valaccodeassignmentmodule.vala +++ b/codegen/valaccodeassignmentmodule.vala @@ -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)); } diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 4c1e60685..9147a5fa0 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -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 diff --git a/codegen/valaccodestructmodule.vala b/codegen/valaccodestructmodule.vala index 7b20f504a..d9237e656 100644 --- a/codegen/valaccodestructmodule.vala +++ b/codegen/valaccodestructmodule.vala @@ -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 diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index abb19f664..3d977784d 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -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 diff --git a/tests/Makefile.am b/tests/Makefile.am index aec6e33f2..c05a68d51 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 index 000000000..ad328deeb --- /dev/null +++ b/tests/delegates/fields-no-target.vala @@ -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; +} + diff --git a/vala/valastruct.vala b/vala/valastruct.vala index bca78510a..1c4ba768c 100644 --- a/vala/valastruct.vala +++ b/vala/valastruct.vala @@ -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; } |