[vala/0.40] codegen: Fix base-access to non-abstract/non-virtual properties
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/0.40] codegen: Fix base-access to non-abstract/non-virtual properties
- Date: Tue, 21 Apr 2020 07:50:35 +0000 (UTC)
commit 74e254aaa4ba277b8ae624748d0843291811d9b8
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Wed Apr 15 14:06:57 2020 +0200
codegen: Fix base-access to non-abstract/non-virtual properties
Don't unconditionally try to access vfuncs and actually emit assignments.
Fixes https://gitlab.gnome.org/GNOME/vala/issues/204
codegen/valaccodebasemodule.vala | 33 ++++++++++++++++----------------
codegen/valaccodememberaccessmodule.vala | 16 +++++++++-------
tests/Makefile.am | 1 +
tests/objects/property-base-access.vala | 25 ++++++++++++++++++++++++
4 files changed, 52 insertions(+), 23 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index d9969f887..bbdec7c4e 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -6127,14 +6127,20 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
}
public void store_property (Property prop, Expression? instance, TargetValue value) {
- if (instance is BaseAccess) {
+ unowned Property base_prop = prop;
+ if (prop.base_property != null) {
+ base_prop = prop.base_property;
+ } else if (prop.base_interface_property != null) {
+ base_prop = prop.base_interface_property;
+ }
+ if (instance is BaseAccess && (base_prop.is_abstract || base_prop.is_virtual)) {
CCodeExpression? vcast = null;
- if (prop.base_property != null) {
- unowned Class base_class = (Class) prop.base_property.parent_symbol;
+ if (base_prop.parent_symbol is Class) {
+ unowned Class base_class = (Class) base_prop.parent_symbol;
vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_CLASS".printf
(get_ccode_upper_case_name (base_class))));
((CCodeFunctionCall) vcast).add_argument (new CCodeIdentifier
("%s_parent_class".printf (get_ccode_lower_case_name (current_class))));
- } else if (prop.base_interface_property != null) {
- unowned Interface base_iface = (Interface)
prop.base_interface_property.parent_symbol;
+ } else if (base_prop.parent_symbol is Interface) {
+ unowned Interface base_iface = (Interface) base_prop.parent_symbol;
vcast = get_this_interface_cexpression (base_iface);
}
if (vcast != null) {
@@ -6147,25 +6153,20 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
ccall.add_argument (cexpr);
ccode.add_expression (ccall);
+ } else {
+ Report.error (instance.source_reference, "internal: Invalid assignment to
`%s'".printf (base_prop.get_full_name ()));
}
return;
}
var set_func = "g_object_set";
-
- var base_property = prop;
- if (!get_ccode_no_accessor_method (prop)) {
- if (prop.base_property != null) {
- base_property = prop.base_property;
- } else if (prop.base_interface_property != null) {
- base_property = prop.base_interface_property;
- }
+ if (!get_ccode_no_accessor_method (prop)) {
if (prop is DynamicProperty) {
set_func = get_dynamic_property_setter_cname ((DynamicProperty) prop);
} else {
- generate_property_accessor_declaration (base_property.set_accessor, cfile);
- set_func = get_ccode_name (base_property.set_accessor);
+ generate_property_accessor_declaration (base_prop.set_accessor, cfile);
+ set_func = get_ccode_name (base_prop.set_accessor);
if (!prop.external && prop.external_package) {
// internal VAPI properties
@@ -6218,7 +6219,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
var delegate_type = (DelegateType) prop.property_type;
if (delegate_type.delegate_symbol.has_target) {
ccall.add_argument (get_delegate_target_cvalue (value));
- if (base_property.set_accessor.value_type.value_owned) {
+ if (base_prop.set_accessor.value_type.value_owned) {
ccall.add_argument (get_delegate_target_destroy_notify_cvalue
(value));
}
}
diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala
index 694cd73a7..e3802fa4b 100644
--- a/codegen/valaccodememberaccessmodule.vala
+++ b/codegen/valaccodememberaccessmodule.vala
@@ -180,13 +180,13 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
return;
}
- if (expr.inner is BaseAccess) {
- var base_prop = prop;
- if (prop.base_property != null) {
- base_prop = prop.base_property;
- } else if (prop.base_interface_property != null) {
- base_prop = prop.base_interface_property;
- }
+ unowned Property base_prop = prop;
+ if (prop.base_property != null) {
+ base_prop = prop.base_property;
+ } else if (prop.base_interface_property != null) {
+ base_prop = prop.base_interface_property;
+ }
+ if (expr.inner is BaseAccess && (base_prop.is_abstract || base_prop.is_virtual)) {
CCodeExpression? vcast = null;
if (base_prop.parent_symbol is Class) {
unowned Class base_class = (Class) base_prop.parent_symbol;
@@ -208,6 +208,8 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule {
} else {
set_cvalue (expr, ccall);
}
+ } else {
+ Report.error (expr.source_reference, "internal: Invalid access to
`%s'".printf (base_prop.get_full_name ()));
}
} else if (prop.binding == MemberBinding.INSTANCE &&
prop.get_accessor.automatic_body &&
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 045ed0187..2cffb4f6c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -333,6 +333,7 @@ TESTS = \
objects/paramspec.vala \
objects/properties.vala \
objects/property-array-length.vala \
+ objects/property-base-access.vala \
objects/property-ownership.vala \
objects/property-read-only-auto.vala \
objects/property-read-only-write.test \
diff --git a/tests/objects/property-base-access.vala b/tests/objects/property-base-access.vala
new file mode 100644
index 000000000..504a310d2
--- /dev/null
+++ b/tests/objects/property-base-access.vala
@@ -0,0 +1,25 @@
+class Foo {
+ public string prop { get; set; }
+
+ public Foo () {
+ prop = "foo";
+ }
+}
+
+class Bar : Foo {
+ public new string prop { get; set; }
+
+ public Bar () {
+ prop = "bar";
+
+ assert (base.prop == "foo");
+ base.prop = "manam";
+ assert (base.prop == "manam");
+
+ assert (prop == "bar");
+ }
+}
+
+void main () {
+ var bar = new Bar ();
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]