[vala/staging] codegen: Allow null to initialize non-null struct inside initializer list




commit 9bd652886ad889213ca7c94a0b846947fdb226d3
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Sun Jun 6 18:11:02 2021 +0200

    codegen: Allow null to initialize non-null struct inside initializer list
    
    Fixes https://gitlab.gnome.org/GNOME/vala/issues/594

 codegen/valaccodebasemodule.vala          | 12 ++++++++++++
 tests/Makefile.am                         |  1 +
 tests/arrays/struct-initializer-null.vala | 12 ++++++++++++
 vala/valainitializerlist.vala             |  2 ++
 4 files changed, 27 insertions(+)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a1897e575..b04b5c781 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2935,6 +2935,10 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                        }
                                }
 
+                               if (list.size <= 0) {
+                                       clist.append (new CCodeConstant ("0"));
+                               }
+
                                if (list.parent_node is Constant
                                    || (list.parent_node is Expression && ((Expression) 
list.parent_node).value_type is ArrayType)) {
                                        set_cvalue (list, clist);
@@ -4402,6 +4406,14 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator {
                                }
                        }
 
+                       // Allow null to initialize non-null struct inside initializer list
+                       if (expr is NullLiteral && expr.parent_node is InitializerList
+                           && expr.target_type != null && expr.target_type.is_real_non_null_struct_type ()) {
+                               var clist = new CCodeInitializerList ();
+                               clist.append (new CCodeConstant ("0"));
+                               set_cvalue (expr, new CCodeCastExpression (clist, get_ccode_name 
(expr.target_type.type_symbol)));
+                       }
+
                        if (!(expr.value_type is ValueType && !expr.value_type.nullable)) {
                                ((GLibValue) expr.target_value).non_null = expr.is_non_null ();
                        }
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 3e754e58e..5dfcd32a9 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -125,6 +125,7 @@ TESTS = \
        arrays/length-no-int-type.test \
        arrays/struct-field-length-cname.vala \
        arrays/struct-field-initializer.vala \
+       arrays/struct-initializer-null.vala \
        arrays/struct-namespaced-initializer.vala \
        arrays/incompatible-integer-elements.test \
        arrays/resize.vala \
diff --git a/tests/arrays/struct-initializer-null.vala b/tests/arrays/struct-initializer-null.vala
new file mode 100644
index 000000000..325f95b34
--- /dev/null
+++ b/tests/arrays/struct-initializer-null.vala
@@ -0,0 +1,12 @@
+struct Foo {
+       public unowned string s;
+       public int i;
+}
+
+const Foo[] FOOS = { { "foo", 23 }, {} };
+const Foo[] BARS = { { "bar", 42 }, null };
+
+void main () {
+       Foo[] foos = { { "foo", 23 }, {} };
+       Foo[] bars = { { "bar", 42 }, null };
+}
diff --git a/vala/valainitializerlist.vala b/vala/valainitializerlist.vala
index 9cb0b91eb..87165439d 100644
--- a/vala/valainitializerlist.vala
+++ b/vala/valainitializerlist.vala
@@ -274,6 +274,8 @@ public class Vala.InitializerList : Expression {
                        unowned UnaryExpression? unary = e as UnaryExpression;
                        if (unary != null && (unary.operator == UnaryOperator.REF || unary.operator == 
UnaryOperator.OUT)) {
                                // TODO check type for ref and out expressions
+                       } else if (e is NullLiteral && e.target_type != null && 
e.target_type.is_real_non_null_struct_type ()) {
+                               // Allow using null instead of {} to initialize struct
                        } else if (!e.value_type.compatible (e.target_type)) {
                                error = true;
                                e.error = true;


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