summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2023-03-27 21:43:25 +0200
committerRico Tzschichholz <ricotz@ubuntu.com>2023-03-27 21:46:32 +0200
commit5a25c2e93043176a86844f2682eba1fcf3216837 (patch)
treec39cecc5393030e9dc5014de7f2d91b4e1816213
parent6541079c11e96328362097b7cec930fc55523b6a (diff)
downloadvala-5a25c2e93043176a86844f2682eba1fcf3216837.tar.gz
vala: Improve initialization of namespace fields with compound literal
Regression of 9c35019ef300082243ef7c71c22088c52d3db38e Fixes https://gitlab.gnome.org/GNOME/vala/issues/1424
-rw-r--r--codegen/valaccodebasemodule.vala9
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/structs/namespace-field-nested-initializer-2.test15
-rw-r--r--tests/structs/namespace-field-nested-initializer.c-expected143
-rw-r--r--tests/structs/namespace-field-nested-initializer.vala15
-rw-r--r--tests/structs/struct-initializer-list-nested.c-expected8
-rw-r--r--vala/valainitializerlist.vala2
7 files changed, 188 insertions, 6 deletions
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 79e9f362a..bf699a076 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -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 {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 6c59fd2e0..4b473a379 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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
index 000000000..8a1557c20
--- /dev/null
+++ b/tests/structs/namespace-field-nested-initializer-2.test
@@ -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
index 000000000..f64e8d1b0
--- /dev/null
+++ b/tests/structs/namespace-field-nested-initializer.c-expected
@@ -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
index 000000000..2ada47dd5
--- /dev/null
+++ b/tests/structs/namespace-field-nested-initializer.vala
@@ -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);
+}
diff --git a/tests/structs/struct-initializer-list-nested.c-expected b/tests/structs/struct-initializer-list-nested.c-expected
index 026dcd0b5..912a53be8 100644
--- a/tests/structs/struct-initializer-list-nested.c-expected
+++ b/tests/structs/struct-initializer-list-nested.c-expected
@@ -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};
diff --git a/vala/valainitializerlist.vala b/vala/valainitializerlist.vala
index a5d92403b..705829df8 100644
--- a/vala/valainitializerlist.vala
+++ b/vala/valainitializerlist.vala
@@ -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 () {