From: Rico Tzschichholz Date: Sun, 6 Jun 2021 16:11:02 +0000 (+0200) Subject: codegen: Allow null to initialize non-null struct inside initializer list X-Git-Tag: 0.50.10~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=af7e5cb12ee849e3ddd0e5d995559fc342f4362e;p=thirdparty%2Fvala.git codegen: Allow null to initialize non-null struct inside initializer list Fixes https://gitlab.gnome.org/GNOME/vala/issues/594 --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 90e1034d6..8bfb867f6 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -2786,6 +2786,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); @@ -4301,6 +4305,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 abf9372e9..38b57c5fa 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -124,6 +124,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 5451739ef..2f4d9aee2 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;