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.53.1~50 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9bd652886ad889213ca7c94a0b846947fdb226d3;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 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;