]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
codegen: Correctly handle chain up of struct creation methods
authorRico Tzschichholz <ricotz@ubuntu.com>
Sat, 11 Dec 2021 09:34:03 +0000 (10:34 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Sat, 11 Dec 2021 16:57:27 +0000 (17:57 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/1264

codegen/valaccodebasemodule.vala
codegen/valaccodemethodmodule.vala
tests/chainup/struct-base-foo.c-expected
tests/chainup/struct-base-foo.vala
tests/chainup/struct-base.c-expected
tests/chainup/struct-this-foo.c-expected
tests/chainup/struct-this-foo.vala
tests/chainup/struct-this.c-expected
vala/valacallableexpression.vala
vala/valamethodcall.vala
vala/valaobjectcreationexpression.vala

index 12bd99db24cf09edafb8636281cf57f8c5ba046d..2e7df70d5c79d678a90fb250a97536b72af8f47e 100644 (file)
@@ -4977,6 +4977,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                } else if (param != null) {
                                        instance = get_cvalue_ (get_parameter_cvalue (param));
                                }
+                       } else if (expr.is_chainup) {
+                               instance = get_this_cexpression ();
                        } else {
                                var temp_value = create_temp_value (expr.type_reference, true, expr);
                                instance = get_cvalue_ (temp_value);
@@ -5033,7 +5035,11 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        }
 
                        if ((st != null && !st.is_simple_type ()) && !(get_ccode_instance_pos (m) < 0)) {
-                               creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
+                               if (expr.is_chainup) {
+                                       creation_call.add_argument (instance);
+                               } else {
+                                       creation_call.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, instance));
+                               }
                        } else if (st != null && get_ccode_name (st) == "va_list") {
                                creation_call.add_argument (instance);
                                if (get_ccode_name (m) == "va_start") {
index 4bc754bb725abee17ec8e9b5825033544b145882..9da195128285eaaf76cfa857def10983f4f583d8 100644 (file)
@@ -662,7 +662,7 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                                        var vardecl = new CCodeVariableDeclarator ("self", default_value_for_type (creturn_type, true));
                                                        vardecl.init0 = true;
                                                        ccode.add_declaration (get_ccode_name (creturn_type), vardecl);
-                                               } else {
+                                               } else if (!((CreationMethod) m).chain_up) {
                                                        // memset needs string.h
                                                        cfile.add_include ("string.h");
                                                        var czero = new CCodeFunctionCall (new CCodeIdentifier ("memset"));
index 635f0104edaadf3300cbe7ef06b38ebdc2f6425c..970b3b938fa712d6a20bfc155dc2b93b8379450d 100644 (file)
@@ -85,9 +85,7 @@ foo_get_type (void)
 void
 bar_init (Bar *self)
 {
-       Foo _tmp0_ = {0};
-       memset (self, 0, sizeof (Bar));
-       foo_init_foo (&_tmp0_);
+       foo_init_foo (self);
        (*self).j = 1;
 }
 
@@ -131,9 +129,12 @@ _vala_main (void)
 {
        Bar bar = {0};
        Bar _tmp0_;
+       Bar _tmp1_;
        bar_init (&bar);
        _tmp0_ = bar;
-       _vala_assert (_tmp0_.j == 1, "bar.j == 1");
+       _vala_assert (_tmp0_.i == 1, "bar.i == 1");
+       _tmp1_ = bar;
+       _vala_assert (_tmp1_.j == 1, "bar.j == 1");
 }
 
 int
index 44aeb3bb13a43517db3253f82580963a3d3d7398..b54bd654dc0df13ee7dfa52163f441ab88f7b452 100644 (file)
@@ -15,6 +15,6 @@ public struct Bar : Foo {
 
 void main () {
        var bar = Bar ();
-       //FIXME assert (bar.i == 1);
+       assert (bar.i == 1);
        assert (bar.j == 1);
 }
index 0a89acf54188f2290b5ed7448edade43fccb2329..99f8f9bb66a5d7df2e8485194b715bac094f0910 100644 (file)
@@ -85,7 +85,6 @@ foo_get_type (void)
 void
 bar_init (Bar *self)
 {
-       memset (self, 0, sizeof (Bar));
        foo_init (self);
        (*self).j = 1;
 }
index 8ee82754fd7b235be709190ab1c6a00d81a0e09d..9c2eb3956a9dc066671dd5516f6f7f02bdfaefce 100644 (file)
@@ -37,9 +37,7 @@ static void _vala_main (void);
 void
 foo_init (Foo *self)
 {
-       Foo _tmp0_ = {0};
-       memset (self, 0, sizeof (Foo));
-       foo_init_foo (&_tmp0_);
+       foo_init_foo (self);
        (*self).j = 1;
 }
 
@@ -90,9 +88,12 @@ _vala_main (void)
 {
        Foo foo = {0};
        Foo _tmp0_;
+       Foo _tmp1_;
        foo_init (&foo);
        _tmp0_ = foo;
-       _vala_assert (_tmp0_.j == 1, "foo.j == 1");
+       _vala_assert (_tmp0_.i == 1, "foo.i == 1");
+       _tmp1_ = foo;
+       _vala_assert (_tmp1_.j == 1, "foo.j == 1");
 }
 
 int
index c0e53beed93f052516a3037902df5ef4331ba76c..b4b835629e473cd1815cbfef5f1bb7e81e4646c2 100644 (file)
@@ -12,6 +12,6 @@ public struct Foo {
 
 void main () {
        var foo = Foo ();
-       //FIXME assert (foo.i == 1);
+       assert (foo.i == 1);
        assert (foo.j == 1);
 }
index 4414aaf7aa32f5e6a03df6be2c37e4b4d3f1e187..b7092ea9a6e4c3b3c2a59e8b06efb60b0c836c40 100644 (file)
@@ -44,7 +44,6 @@ foo_init (Foo *self)
 void
 foo_init_bar (Foo *self)
 {
-       memset (self, 0, sizeof (Foo));
        foo_init (self);
        (*self).i = 1;
 }
index 9439cd2a2c3e90081c114f4590837d21e0ec34bb..930c7a0a2452125114245c354da8e5654a7fb5bb 100644 (file)
@@ -31,6 +31,11 @@ public interface Vala.CallableExpression : Expression {
         */
        public abstract bool is_yield_expression { get; set; }
 
+       /**
+        * Whether it is a creation chain up.
+        */
+       public abstract bool is_chainup { get; set; }
+
        /**
         * Appends the specified expression to the list of arguments.
         *
index aff7db77a44d8f3ea8d0d525d298f90315be1fb9..70ad8fb6a926f050bde08c84db56ba2d35aee812 100644 (file)
@@ -46,7 +46,7 @@ public class Vala.MethodCall : Expression, CallableExpression {
         */
        public bool is_constructv_chainup { get; private set; }
 
-       public bool is_chainup { get; private set; }
+       public bool is_chainup { get; set; }
 
        private Expression _call;
 
@@ -319,6 +319,7 @@ public class Vala.MethodCall : Expression, CallableExpression {
 
                        var struct_creation_expression = new ObjectCreationExpression ((MemberAccess) call, source_reference);
                        struct_creation_expression.struct_creation = true;
+                       struct_creation_expression.is_chainup = is_chainup;
                        foreach (Expression arg in argument_list) {
                                struct_creation_expression.add_argument (arg);
                        }
index a6ce8a14f7943d2d45ac5bccc5504806f51167d2..dc2bd8f6caf03850ce7ccfe7535f30572759f723 100644 (file)
@@ -53,6 +53,8 @@ public class Vala.ObjectCreationExpression : Expression, CallableExpression {
 
        public bool is_yield_expression { get; set; }
 
+       public bool is_chainup { get; set; }
+
        public bool struct_creation { get; set; }
 
        private List<Expression> argument_list = new ArrayList<Expression> ();