]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Fix assignment of casted struct value to property
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 6 Jan 2021 11:19:10 +0000 (12:19 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 6 Jan 2021 11:19:10 +0000 (12:19 +0100)
Usage of address-of operator requires lvalue access. Therefore use a
temporary variable to be passed to property setter.

Fixes https://gitlab.gnome.org/GNOME/vala/issues/1126

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/objects/property-real-struct-assignment.vala [new file with mode: 0644]

index d6463a8aa4590b0f08a41e2376b68f762a4e33dc..0be29ed997f27a83b4a0a794aa83eabb361c60e1 100644 (file)
@@ -6225,6 +6225,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                ccall.add_argument ((CCodeExpression) get_ccodenode (instance));
                                var cexpr = get_cvalue_ (value);
                                if (prop.property_type.is_real_non_null_struct_type ()) {
+                                       //TODO Make use of get_lvalue (value)
+                                       if (!(cexpr is CCodeConstant || cexpr is CCodeIdentifier)) {
+                                               var temp_value = store_temp_value (value, instance);
+                                               cexpr = get_cvalue_ (temp_value);
+                                       }
                                        cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
                                }
                                ccall.add_argument (cexpr);
@@ -6281,6 +6286,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                var cexpr = get_cvalue_ (value);
 
                if (prop.property_type.is_real_non_null_struct_type ()) {
+                       //TODO Make use of get_lvalue (value)
+                       if (!(cexpr is CCodeConstant || cexpr is CCodeIdentifier)) {
+                               var temp_value = store_temp_value (value, instance);
+                               cexpr = get_cvalue_ (temp_value);
+                       }
                        cexpr = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, cexpr);
                }
 
index e0a9e19da05bb8b17d6ae3a701951009598d47b2..bd4b19daa3e11dcaf68c9fa3f9bca358bfc95757 100644 (file)
@@ -464,6 +464,7 @@ TESTS = \
        objects/property-delegate.vala \
        objects/property-delegate-owned.vala \
        objects/property-gboxed-nullable.vala \
+       objects/property-real-struct-assignment.vala \
        objects/property-real-struct-no-accessor.test \
        objects/property-simple-type-struct-nullable.vala \
        objects/property-static.vala \
diff --git a/tests/objects/property-real-struct-assignment.vala b/tests/objects/property-real-struct-assignment.vala
new file mode 100644 (file)
index 0000000..2679076
--- /dev/null
@@ -0,0 +1,56 @@
+struct Foo {
+       string s;
+}
+
+Foo? get_foo () {
+       return { "foo" };
+}
+
+class Manam : Object {
+       public virtual Foo faz { get; set; }
+}
+
+class Bar : Manam {
+       public Foo foo { get; set; }
+
+       public Bar () {
+               {
+                       this.foo = get_foo ();
+               }
+               {
+                       base.faz = get_foo ();
+               }
+               {
+                       this.foo = (!) get_foo ();
+               }
+               {
+                       base.faz = (!) get_foo ();
+               }
+               {
+                       this.foo = (Foo) get_foo ();
+               }
+               {
+                       base.faz = (Foo) get_foo ();
+               }
+               {
+                       var f = get_foo ();
+                       this.foo = (!) f;
+               }
+               {
+                       var f = get_foo ();
+                       base.faz = (!) f;
+               }
+               {
+                       var f = get_foo ();
+                       this.foo = (Foo) f;
+               }
+               {
+                       var f = get_foo ();
+                       base.faz = (Foo) f;
+               }
+       }
+}
+
+void main() {
+       var bar = new Bar ();
+}