]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
vala: Allow assignment of namespace fields with inline allocated arrays
authorRico Tzschichholz <ricotz@ubuntu.com>
Mon, 20 Mar 2023 14:18:00 +0000 (15:18 +0100)
committerRico Tzschichholz <ricotz@ubuntu.com>
Mon, 20 Mar 2023 15:25:10 +0000 (16:25 +0100)
Fixes https://gitlab.gnome.org/GNOME/vala/issues/945

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/arrays/inline-namespace-field.c-expected [new file with mode: 0644]
tests/arrays/inline-namespace-field.vala [new file with mode: 0644]
vala/valainitializerlist.vala

index cf72070eb7c0d90928d7a3acc147c6bd93a311cc..79e9f362a5c88098f8a7d951f2ed01442a81da29 100644 (file)
@@ -1458,6 +1458,8 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
        public static bool is_constant_ccode_expression (CCodeExpression cexpr) {
                if (cexpr is CCodeConstant || cexpr is CCodeConstantIdentifier) {
                        return true;
+               } else if (cexpr is CCodeInitializerList) {
+                       return true;
                } else if (cexpr is CCodeCastExpression) {
                        var ccast = (CCodeCastExpression) cexpr;
                        return is_constant_ccode_expression (ccast.inner);
index 7b4317a18826e10cc9f266d83a890038db258c59..9b005ce7613c974c370f811ae138f78f455d0680 100644 (file)
@@ -145,6 +145,7 @@ TESTS = \
        arrays/inline-field.test \
        arrays/inline-local-instantiation.test \
        arrays/inline-local-variable.test \
+       arrays/inline-namespace-field.vala \
        arrays/inline-ownership-transfer.test \
        arrays/inline-parameter.test \
        arrays/inline-struct.vala \
diff --git a/tests/arrays/inline-namespace-field.c-expected b/tests/arrays/inline-namespace-field.c-expected
new file mode 100644 (file)
index 0000000..0328009
--- /dev/null
@@ -0,0 +1,50 @@
+/* arrays_inline_namespace_field.c generated by valac, the Vala compiler
+ * generated from arrays_inline_namespace_field.vala, do not modify */
+
+#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 _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);
+
+VALA_EXTERN const gchar* foo[2];
+const gchar* foo[2] = {"foo", "bar"};
+VALA_EXTERN gint bar[3];
+gint bar[3] = {23, 42, 4711};
+
+static void _vala_main (void);
+
+static void
+_vala_main (void)
+{
+       const gchar* _tmp0_;
+       gint _tmp1_;
+       _tmp0_ = foo[0];
+       _vala_assert (g_strcmp0 (_tmp0_, "foo") == 0, "foo[0] == \"foo\"");
+       _vala_assert (2 == 2, "foo.length == 2");
+       _tmp1_ = bar[1];
+       _vala_assert (_tmp1_ == 42, "bar[1] == 42");
+       _vala_assert (3 == 3, "bar.length == 3");
+}
+
+int
+main (int argc,
+      char ** argv)
+{
+       _vala_main ();
+       return 0;
+}
+
diff --git a/tests/arrays/inline-namespace-field.vala b/tests/arrays/inline-namespace-field.vala
new file mode 100644 (file)
index 0000000..0eb4b6d
--- /dev/null
@@ -0,0 +1,9 @@
+unowned string foo[2] = { "foo", "bar" };
+int bar[3] = { 23, 42, 4711 };
+
+void main () {
+       assert (foo[0] == "foo");
+       assert (foo.length == 2);
+       assert (bar[1] == 42);
+       assert (bar.length == 3);
+}
index 8d3777b7735c9aca219ddd8f86e6b4a214c82492..a5d92403b53c3582331e961c2f9ca6467a393811 100644 (file)
@@ -149,16 +149,19 @@ public class Vala.InitializerList : Expression {
                        unowned ArrayType array_type = (ArrayType) target_type;
 
                        bool requires_constants_only = false;
+                       bool is_global_constant_inline = false;
                        unowned CodeNode? node = parent_node;
                        while (node != null) {
                                if (node is Constant) {
                                        requires_constants_only = true;
                                        break;
+                               } else if (node is Field && ((Field) node).parent_symbol is Namespace) {
+                                       is_global_constant_inline = array_type.inline_allocated && is_constant ();
                                }
                                node = node.parent_node;
                        }
 
-                       if (!(parent_node is ArrayCreationExpression) && !requires_constants_only
+                       if (!(parent_node is ArrayCreationExpression) && !requires_constants_only && !is_global_constant_inline
                            && (!(parent_node is InitializerList) || ((InitializerList) parent_node).target_type.type_symbol is Struct)) {
                                // transform shorthand form
                                //     int[] array = { 42 };