[vala/staging] codegen: Fix variadic constructors for compact classes and structs



commit 700127449b3825ecb262e541a397ebdd065b45cd
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Wed Jun 23 10:56:01 2021 +0200

    codegen: Fix variadic constructors for compact classes and structs
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/1195

 codegen/valaccodebasemodule.vala                   |  3 +-
 codegen/valaccodemethodmodule.vala                 | 19 +++++++-----
 tests/Makefile.am                                  |  4 ++-
 ...adic.test => constructor-variadic-invalid.test} |  0
 tests/objects/constructor-variadic.vala            | 35 ++++++++++++++++++++++
 tests/structs/constructor-variadic.vala            | 18 +++++++++++
 6 files changed, 70 insertions(+), 9 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index b04b5c781..4b120dec9 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -5027,7 +5027,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                        } else if (st != null && get_ccode_name (st) == "va_list") {
                                creation_call.add_argument (instance);
                                if (get_ccode_name (m) == "va_start") {
-                                       if (in_creation_method) {
+                                       unowned Class? parent = current_method.parent_symbol as Class;
+                                       if (in_creation_method && parent != null && !parent.is_compact) {
                                                creation_call = new CCodeFunctionCall (new CCodeIdentifier 
("va_copy"));
                                                creation_call.add_argument (instance);
                                                creation_call.add_argument (new CCodeIdentifier 
("_vala_va_list"));
diff --git a/codegen/valaccodemethodmodule.vala b/codegen/valaccodemethodmodule.vala
index 89079688c..840aa14bc 100644
--- a/codegen/valaccodemethodmodule.vala
+++ b/codegen/valaccodemethodmodule.vala
@@ -324,11 +324,6 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
         * with _new in visit_creation_method).
         */
        public override void visit_method (Method m) {
-               string real_name = get_ccode_real_name (m);
-               if (m is CreationMethod && m.is_variadic ()) {
-                       real_name = get_ccode_constructv_name ((CreationMethod) m);
-               }
-
                push_context (new EmitContext (m));
                push_line (m.source_reference);
 
@@ -337,8 +332,10 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
 
                bool profile = m.get_attribute ("Profile") != null;
 
+               string real_name = get_ccode_real_name (m);
+
                if (m is CreationMethod) {
-                       var cl = current_type_symbol as Class;
+                       unowned Class? cl =  m.parent_symbol as Class;
                        if (cl != null && !cl.is_compact) {
                                if (cl.base_class == null) {
                                        in_fundamental_creation_method = true;
@@ -346,6 +343,9 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
                                        in_gobject_creation_method = true;
                                }
                        }
+                       if (cl != null && !cl.is_compact && m.is_variadic ()) {
+                               real_name = get_ccode_constructv_name ((CreationMethod) m);
+                       }
                }
 
                var creturn_type = get_callable_creturn_type (m);
@@ -1247,7 +1247,12 @@ public abstract class Vala.CCodeMethodModule : CCodeStructModule {
        public override void visit_creation_method (CreationMethod m) {
                push_line (m.source_reference);
 
-               ellipses_to_valist = true;
+               unowned Class? cl =  m.parent_symbol as Class;
+               if (cl != null && !cl.is_compact) {
+                       ellipses_to_valist = true;
+               } else {
+                       ellipses_to_valist = false;
+               }
                visit_method (m);
                ellipses_to_valist = false;
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5dfcd32a9..6f3064dad 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -343,6 +343,7 @@ TESTS = \
        structs/struct-static-field-initializer.test \
        structs/struct-static-property-initializer.test \
        structs/structs.vala \
+       structs/constructor-variadic.vala \
        structs/constructor-wrong-name.test \
        structs/default-gtype.vala \
        structs/gmutex.vala \
@@ -442,7 +443,8 @@ TESTS = \
        objects/compact-class-custom-ref.vala \
        objects/constructor-abstract-public.test \
        objects/constructor-inner-error.vala \
-       objects/constructor-variadic.test \
+       objects/constructor-variadic.vala \
+       objects/constructor-variadic-invalid.test \
        objects/constructor-wrong-name.test \
        objects/constructors.vala \
        objects/destructors.vala \
diff --git a/tests/objects/constructor-variadic.test b/tests/objects/constructor-variadic-invalid.test
similarity index 100%
rename from tests/objects/constructor-variadic.test
rename to tests/objects/constructor-variadic-invalid.test
diff --git a/tests/objects/constructor-variadic.vala b/tests/objects/constructor-variadic.vala
new file mode 100644
index 000000000..58a97fe1f
--- /dev/null
+++ b/tests/objects/constructor-variadic.vala
@@ -0,0 +1,35 @@
+class Foo {
+       public string s;
+
+       public Foo (string first_arg, ...) {
+               assert (first_arg == "foo");
+               va_list args = va_list ();
+               string second_arg = args.arg<string> ();
+               assert (second_arg == "bar");
+               s = first_arg + second_arg;
+       }
+}
+
+[Compact]
+class Bar {
+       public string s;
+
+       public Bar (string first_arg, ...) {
+               assert (first_arg == "bar");
+               va_list args = va_list ();
+               string second_arg = args.arg<string> ();
+               assert (second_arg == "foo");
+               s = first_arg + second_arg;
+       }
+}
+
+void main () {
+       {
+               var foo = new Foo ("foo", "bar");
+               assert (foo.s == "foobar");
+       }
+       {
+               var bar = new Bar ("bar", "foo");
+               assert (bar.s == "barfoo");
+       }
+}
diff --git a/tests/structs/constructor-variadic.vala b/tests/structs/constructor-variadic.vala
new file mode 100644
index 000000000..2602fe20b
--- /dev/null
+++ b/tests/structs/constructor-variadic.vala
@@ -0,0 +1,18 @@
+struct Foo {
+       public string s;
+
+       public Foo (string first_arg, ...) {
+               assert (first_arg == "foo");
+               va_list args = va_list ();
+               string second_arg = args.arg<string> ();
+               assert (second_arg == "bar");
+               s = first_arg + second_arg;
+       }
+}
+
+void main () {
+       {
+               var foo = Foo ("foo", "bar");
+               assert (foo.s == "foobar");
+       }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]