summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2018-05-30 17:02:42 +0200
committerRico Tzschichholz <ricotz@ubuntu.com>2018-05-31 13:14:00 +0200
commit0efcee2892c805d15fe46d4c9197669a0c51ad5f (patch)
treeaceb3f7921d26594c21199216bc41623811f3a5a
parent72fab93ba9a5027fbdd30cabfa5cd32482dad07f (diff)
downloadvala-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.vala2
-rw-r--r--codegen/valaccodebasemodule.vala12
-rw-r--r--codegen/valaccodestructmodule.vala4
-rw-r--r--codegen/valagtypemodule.vala4
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/delegates/fields-no-target.vala39
-rw-r--r--vala/valastruct.vala1
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;
}