]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix base-access from within overriding struct-property-accessor
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 8 Mar 2017 21:55:52 +0000 (22:55 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 8 Mar 2017 22:01:48 +0000 (23:01 +0100)
Based on patch by gandalfn

https://bugzilla.gnome.org/show_bug.cgi?id=764481

codegen/valaccodebasemodule.vala
codegen/valaccodememberaccessmodule.vala
codegen/valagtypemodule.vala
tests/Makefile.am
tests/objects/bug764481.vala [new file with mode: 0644]

index 84d5982b9197db90969ed41a7def8268827afb22..3a68264d20d73a24f05a184683267c372974efe3 100644 (file)
@@ -5880,7 +5880,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) {
@@ -5889,7 +5893,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);
                        }
index 2f9f50d6b4cde1fbe26694df6e7c7ebf22623162..dd7a2aea75c1d8ab53f40b8b78063b722a2b6f3d 100644 (file)
@@ -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 &&
index 11d2f6d48b5f1e85234fba5fc9d31a45653610f1..ab89c5e11e5fcbeea2bca52f228d9e0e74617770 100644 (file)
@@ -2297,7 +2297,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;
index 132b0b539fe9094df0910715a49b056d6f65b135..359942df4982b73ccef27205e8e3786bf1fd0ef7 100644 (file)
@@ -206,6 +206,7 @@ TESTS = \
        objects/bug702846.vala \
        objects/bug751338.vala \
        objects/bug760031.test \
+       objects/bug764481.vala \
        objects/bug767092.test \
        objects/bug768823.test \
        objects/bug773956-1.test \
diff --git a/tests/objects/bug764481.vala b/tests/objects/bug764481.vala
new file mode 100644 (file)
index 0000000..92c82c8
--- /dev/null
@@ -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);
+}