diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2017-03-08 22:55:52 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2017-03-16 08:11:15 +0100 |
commit | 7f2c432b2d7e12032618e218cd4a0e92e794ce2f (patch) | |
tree | f573c3842f738ad251f4a580a958c07320fa854c | |
parent | 76a14eabbb9d330b5910db38116829df0a1bf4fa (diff) | |
download | vala-7f2c432b2d7e12032618e218cd4a0e92e794ce2f.tar.gz |
codegen: Fix base-access from within overriding struct-property-accessor
Based on patch by gandalfn
https://bugzilla.gnome.org/show_bug.cgi?id=764481
-rw-r--r-- | codegen/valaccodebasemodule.vala | 12 | ||||
-rw-r--r-- | codegen/valaccodememberaccessmodule.vala | 20 | ||||
-rw-r--r-- | codegen/valagtypemodule.vala | 2 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/objects/bug764481.vala | 55 |
5 files changed, 85 insertions, 5 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 25e2c0d42..30132bde6 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -5814,7 +5814,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "set_%s".printf (prop.name))); ccall.add_argument ((CCodeExpression) get_ccodenode (instance)); - ccall.add_argument (get_cvalue_ (value)); + var cexpr = get_cvalue_ (value); + if (prop.property_type.is_real_non_null_struct_type ()) { + cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr); + } + ccall.add_argument (cexpr); ccode.add_expression (ccall); } else if (prop.base_interface_property != null) { @@ -5823,7 +5827,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), "set_%s".printf (prop.name))); ccall.add_argument ((CCodeExpression) get_ccodenode (instance)); - ccall.add_argument (get_cvalue_ (value)); + var cexpr = get_cvalue_ (value); + if (prop.property_type.is_real_non_null_struct_type ()) { + cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr); + } + ccall.add_argument (cexpr); ccode.add_expression (ccall); } diff --git a/codegen/valaccodememberaccessmodule.vala b/codegen/valaccodememberaccessmodule.vala index 229b8cfb2..e21364359 100644 --- a/codegen/valaccodememberaccessmodule.vala +++ b/codegen/valaccodememberaccessmodule.vala @@ -182,14 +182,30 @@ public abstract class Vala.CCodeMemberAccessModule : CCodeControlFlowModule { var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, "get_%s".printf (prop.name))); ccall.add_argument (get_cvalue (expr.inner)); - set_cvalue (expr, ccall); + if (prop.property_type.is_real_non_null_struct_type ()) { + var temp_value = (GLibValue) create_temp_value (prop.get_accessor.value_type, false, expr); + expr.target_value = load_temp_value (temp_value); + var ctemp = get_cvalue_ (temp_value); + ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp)); + ccode.add_expression (ccall); + } else { + set_cvalue (expr, ccall); + } } else if (base_prop.parent_symbol is Interface) { var base_iface = (Interface) base_prop.parent_symbol; string parent_iface_var = "%s_%s_parent_iface".printf (get_ccode_lower_case_name (current_class), get_ccode_lower_case_name (base_iface)); var ccall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (new CCodeIdentifier (parent_iface_var), "get_%s".printf (prop.name))); ccall.add_argument (get_cvalue (expr.inner)); - set_cvalue (expr, ccall); + if (prop.property_type.is_real_non_null_struct_type ()) { + var temp_value = (GLibValue) create_temp_value (prop.get_accessor.value_type, false, expr); + expr.target_value = load_temp_value (temp_value); + var ctemp = get_cvalue_ (temp_value); + ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, ctemp)); + ccode.add_expression (ccall); + } else { + set_cvalue (expr, ccall); + } } } else if (prop.binding == MemberBinding.INSTANCE && prop.get_accessor.automatic_body && diff --git a/codegen/valagtypemodule.vala b/codegen/valagtypemodule.vala index 1e1b9e30a..d279d9413 100644 --- a/codegen/valagtypemodule.vala +++ b/codegen/valagtypemodule.vala @@ -2266,7 +2266,7 @@ public class Vala.GTypeModule : GErrorModule { var cdefault = default_value_for_type (ret_type, false); if (cdefault != null) { ccheck.add_argument (cdefault); - } else if (ret_type.data_type is Struct && ((Struct) ret_type.data_type).is_simple_type ()) { + } else if (ret_type.data_type is Struct && !((Struct) ret_type.data_type).is_simple_type ()) { ccheck.add_argument (new CCodeIdentifier ("result")); } else { return; diff --git a/tests/Makefile.am b/tests/Makefile.am index c69dd7099..a5f52e02a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -172,6 +172,7 @@ TESTS = \ objects/bug702736.vala \ objects/bug702846.vala \ objects/bug751338.vala \ + objects/bug764481.vala \ objects/bug767092.test \ objects/bug768823.test \ objects/bug766739.vala \ diff --git a/tests/objects/bug764481.vala b/tests/objects/bug764481.vala new file mode 100644 index 000000000..92c82c83a --- /dev/null +++ b/tests/objects/bug764481.vala @@ -0,0 +1,55 @@ +[SimpleType] +[CCode (has_type_id = false)] +struct Minim { + int a; +} + +struct Manam { + int a; +} + +class BaseFoo : Object { + public virtual Manam st { get; set; } + public virtual Minim sst { get; set; } +} + +class Foo : Object { + public virtual Manam st { get; set; } + public virtual Minim sst { get; set; } +} + +class Bar : Foo { + public override Manam st { + get { return base.st; } + set { base.st = value; } + } + public override Minim sst { + get { return base.sst; } + set { base.sst = value; } + } +} + +class Baz : BaseFoo { + public override Manam st { + get { return base.st; } + set { base.st = value; } + } + public override Minim sst { + get { return base.sst; } + set { base.sst = value; } + } +} + +void main () { + var bar = new Bar (); + bar.st = { 42 }; + bar.sst = { 42 }; + assert (bar.st.a == 42); + assert (bar.sst.a == 42); + + var baz = new Baz (); + baz.st = { 23 }; + baz.sst = { 23 }; + assert (baz.st.a == 23); + assert (baz.sst.a == 23); +} |