]> 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>
Sat, 9 Jan 2021 19:58:09 +0000 (20:58 +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 5974c577a6ce28d872637c6f43367da3352e60b8..27eb82326f7a27a0434c7030cceea1cd33087980 100644 (file)
@@ -6215,6 +6215,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);
@@ -6271,6 +6276,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 36e09469e26ccd1a345132f030690c9a9f6d2eef..e8935b50db02453b5329c8708f6318a733ae643d 100644 (file)
@@ -385,6 +385,7 @@ TESTS = \
        objects/property-construct-only-write.test \
        objects/property-construct-only-write-foreign.test \
        objects/property-delegate-owned.vala \
+       objects/property-real-struct-assignment.vala \
        objects/property-static.vala \
        objects/regex.vala \
        objects/signals.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 ();
+}