]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Improve initialization of namespace fields with compound literal
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 27 Mar 2023 19:43:25 +0000 (21:43 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Mon, 27 Mar 2023 19:46:32 +0000 (21:46 +0200)
Regression of 9c35019ef300082243ef7c71c22088c52d3db38e

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

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/structs/namespace-field-nested-initializer-2.test [new file with mode: 0644]
tests/structs/namespace-field-nested-initializer.c-expected [new file with mode: 0644]
tests/structs/namespace-field-nested-initializer.vala [new file with mode: 0644]
tests/structs/struct-initializer-list-nested.c-expected
vala/valainitializerlist.vala

index 79e9f362a5c88098f8a7d951f2ed01442a81da29..bf699a076c9d7d3b3f0acaa09ba1a97a8b79647b 100644 (file)
@@ -2826,6 +2826,13 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                return load_temp_value (lvalue);
        }
 
+       bool is_static_field_initializer (CodeNode node) {
+               if (node is InitializerList) {
+                       return is_static_field_initializer (node.parent_node);
+               }
+               return node is Constant || (node is Field && ((Field) node).binding == MemberBinding.STATIC);
+       }
+
        public override void visit_initializer_list (InitializerList list) {
                if (list.target_type.type_symbol is Struct) {
                        /* initializer is used as struct initializer */
@@ -2873,7 +2880,7 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        clist.append (new CCodeConstant ("0"));
                                }
 
-                               if (list.parent_node is Constant
+                               if (is_static_field_initializer (list.parent_node)
                                    || (list.parent_node is Expression && ((Expression) list.parent_node).value_type is ArrayType)) {
                                        set_cvalue (list, clist);
                                } else {
index 6c59fd2e0c9599499d8ff68c77dcba2ae04e51c7..4b473a379b5a4129d23f5e766bdc37f04769a02c 100644 (file)
@@ -411,6 +411,8 @@ TESTS = \
        structs/gtype-base-struct.vala \
        structs/gvalue.vala \
        structs/gvalue-implicit-comparison.vala \
+       structs/namespace-field-nested-initializer.vala \
+       structs/namespace-field-nested-initializer-2.test \
        structs/properties.vala \
        structs/simple-type-constructor.vala \
        structs/simple-type-boxed.vala \
diff --git a/tests/structs/namespace-field-nested-initializer-2.test b/tests/structs/namespace-field-nested-initializer-2.test
new file mode 100644 (file)
index 0000000..8a1557c
--- /dev/null
@@ -0,0 +1,15 @@
+Invalid Code
+
+struct Foo {
+       public string s;
+       public int i;
+}
+
+struct Bar {
+       public Foo foo;
+}
+
+Bar bar = {{"foo", 42}};
+
+void main () {
+}
diff --git a/tests/structs/namespace-field-nested-initializer.c-expected b/tests/structs/namespace-field-nested-initializer.c-expected
new file mode 100644 (file)
index 0000000..f64e8d1
--- /dev/null
@@ -0,0 +1,143 @@
+/* structs_namespace_field_nested_initializer.c generated by valac, the Vala compiler
+ * generated from structs_namespace_field_nested_initializer.vala, do not modify */
+
+#include <glib-object.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#if !defined(VALA_EXTERN)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#define VALA_EXTERN __declspec(dllexport) extern
+#elif __GNUC__ >= 4
+#define VALA_EXTERN __attribute__((visibility("default"))) extern
+#else
+#define VALA_EXTERN extern
+#endif
+#endif
+
+#define TYPE_FOO (foo_get_type ())
+typedef struct _Foo Foo;
+
+#define TYPE_BAR (bar_get_type ())
+typedef struct _Bar Bar;
+#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
+#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
+#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
+
+struct _Foo {
+       const gchar* s;
+       gint i;
+};
+
+struct _Bar {
+       Foo foo;
+};
+
+VALA_EXTERN Bar bar;
+Bar bar = {{"foo", 42}};
+
+VALA_EXTERN GType foo_get_type (void) G_GNUC_CONST ;
+VALA_EXTERN Foo* foo_dup (const Foo* self);
+VALA_EXTERN void foo_free (Foo* self);
+VALA_EXTERN GType bar_get_type (void) G_GNUC_CONST ;
+VALA_EXTERN Bar* bar_dup (const Bar* self);
+VALA_EXTERN void bar_free (Bar* self);
+static void _vala_main (void);
+
+Foo*
+foo_dup (const Foo* self)
+{
+       Foo* dup;
+       dup = g_new0 (Foo, 1);
+       memcpy (dup, self, sizeof (Foo));
+       return dup;
+}
+
+void
+foo_free (Foo* self)
+{
+       g_free (self);
+}
+
+static GType
+foo_get_type_once (void)
+{
+       GType foo_type_id;
+       foo_type_id = g_boxed_type_register_static ("Foo", (GBoxedCopyFunc) foo_dup, (GBoxedFreeFunc) foo_free);
+       return foo_type_id;
+}
+
+GType
+foo_get_type (void)
+{
+       static volatile gsize foo_type_id__once = 0;
+       if (g_once_init_enter (&foo_type_id__once)) {
+               GType foo_type_id;
+               foo_type_id = foo_get_type_once ();
+               g_once_init_leave (&foo_type_id__once, foo_type_id);
+       }
+       return foo_type_id__once;
+}
+
+Bar*
+bar_dup (const Bar* self)
+{
+       Bar* dup;
+       dup = g_new0 (Bar, 1);
+       memcpy (dup, self, sizeof (Bar));
+       return dup;
+}
+
+void
+bar_free (Bar* self)
+{
+       g_free (self);
+}
+
+static GType
+bar_get_type_once (void)
+{
+       GType bar_type_id;
+       bar_type_id = g_boxed_type_register_static ("Bar", (GBoxedCopyFunc) bar_dup, (GBoxedFreeFunc) bar_free);
+       return bar_type_id;
+}
+
+GType
+bar_get_type (void)
+{
+       static volatile gsize bar_type_id__once = 0;
+       if (g_once_init_enter (&bar_type_id__once)) {
+               GType bar_type_id;
+               bar_type_id = bar_get_type_once ();
+               g_once_init_leave (&bar_type_id__once, bar_type_id);
+       }
+       return bar_type_id__once;
+}
+
+static void
+_vala_main (void)
+{
+       Bar _tmp0_;
+       Foo _tmp1_;
+       const gchar* _tmp2_;
+       Bar _tmp3_;
+       Foo _tmp4_;
+       _tmp0_ = bar;
+       _tmp1_ = _tmp0_.foo;
+       _tmp2_ = _tmp1_.s;
+       _vala_assert (g_strcmp0 (_tmp2_, "foo") == 0, "bar.foo.s == \"foo\"");
+       _tmp3_ = bar;
+       _tmp4_ = _tmp3_.foo;
+       _vala_assert (_tmp4_.i == 42, "bar.foo.i == 42");
+}
+
+int
+main (int argc,
+      char ** argv)
+{
+       _vala_main ();
+       return 0;
+}
+
diff --git a/tests/structs/namespace-field-nested-initializer.vala b/tests/structs/namespace-field-nested-initializer.vala
new file mode 100644 (file)
index 0000000..2ada47d
--- /dev/null
@@ -0,0 +1,15 @@
+struct Foo {
+       public unowned string s;
+       public int i;
+}
+
+struct Bar {
+       public Foo foo;
+}
+
+Bar bar = {{"foo", 42}};
+
+void main () {
+       assert (bar.foo.s == "foo");
+       assert (bar.foo.i == 42);
+}
index 026dcd0b59ffdf856df265b51c375c728f400898..912a53be8cb6b4aac7aa3c29350a7cfae585c6bc 100644 (file)
@@ -75,8 +75,8 @@ VALA_EXTERN Baz* baz_dup (const Baz* self);
 VALA_EXTERN void baz_free (Baz* self);
 static void _vala_main (void);
 
-const Baz BAZ = {(Foo) {23, 42}};
-const Baz BAZ_A[2] = {{(Foo) {23, 42}}, {(Foo) {47, 11}}};
+const Baz BAZ = {{23, 42}};
+const Baz BAZ_A[2] = {{{23, 42}}, {{47, 11}}};
 
 Foo*
 foo_dup (const Foo* self)
@@ -286,10 +286,10 @@ static void
 _vala_main (void)
 {
        {
-               static const Baz LOCAL_BAZ = {(Foo) {23, 42}};
+               static const Baz LOCAL_BAZ = {{23, 42}};
        }
        {
-               static const Baz LOCAL_BAZ_A[2] = {{(Foo) {23, 42}}, {(Foo) {47, 11}}};
+               static const Baz LOCAL_BAZ_A[2] = {{{23, 42}}, {{47, 11}}};
        }
        {
                Bar bar = {0};
index a5d92403b53c3582331e961c2f9ca6467a393811..705829df8f9a3d280c8e5771d9cd5d41325631a5 100644 (file)
@@ -84,7 +84,7 @@ public class Vala.InitializerList : Expression {
                                return false;
                        }
                }
-               return true;
+               return !(target_type == null || target_type.is_disposable ());
        }
 
        public override bool is_pure () {