From: Jürg Billeter Date: Sun, 27 Sep 2009 08:40:08 +0000 (+0200) Subject: Fix non-constant struct initializer lists X-Git-Tag: 0.7.7~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b59b98fb4bba4726373e4c9372f03cd459d207b;p=thirdparty%2Fvala.git Fix non-constant struct initializer lists Fixes bug 583603. --- diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index a00bd2421..d20c8fac0 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -2130,31 +2130,67 @@ internal class Vala.CCodeBaseModule : CCodeModule { /* initializer is used as struct initializer */ var st = (Struct) list.target_type.data_type; - var clist = new CCodeInitializerList (); + if (list.parent_node is Constant || list.parent_node is Field || list.parent_node is InitializerList) { + var clist = new CCodeInitializerList (); + + var field_it = st.get_fields ().iterator (); + foreach (Expression expr in list.get_initializers ()) { + Field field = null; + while (field == null) { + field_it.next (); + field = field_it.get (); + if (field.binding != MemberBinding.INSTANCE) { + // we only initialize instance fields + field = null; + } + } - var field_it = st.get_fields ().iterator (); - foreach (Expression expr in list.get_initializers ()) { - Field field = null; - while (field == null) { - field_it.next (); - field = field_it.get (); - if (field.binding != MemberBinding.INSTANCE) { - // we only initialize instance fields - field = null; + var cexpr = (CCodeExpression) expr.ccodenode; + + string ctype = field.get_ctype (); + if (ctype != null) { + cexpr = new CCodeCastExpression (cexpr, ctype); } + + clist.append (cexpr); } - var cexpr = (CCodeExpression) expr.ccodenode; + list.ccodenode = clist; + } else { + // used as expression + var temp_decl = get_temp_variable (list.target_type, false, list); + temp_vars.add (temp_decl); - string ctype = field.get_ctype (); - if (ctype != null) { - cexpr = new CCodeCastExpression (cexpr, ctype); + var instance = get_variable_cexpression (get_variable_cname (temp_decl.name)); + + var ccomma = new CCodeCommaExpression (); + + var field_it = st.get_fields ().iterator (); + foreach (Expression expr in list.get_initializers ()) { + Field field = null; + while (field == null) { + field_it.next (); + field = field_it.get (); + if (field.binding != MemberBinding.INSTANCE) { + // we only initialize instance fields + field = null; + } + } + + var cexpr = (CCodeExpression) expr.ccodenode; + + string ctype = field.get_ctype (); + if (ctype != null) { + cexpr = new CCodeCastExpression (cexpr, ctype); + } + + var lhs = new CCodeMemberAccess (instance, field.get_cname ());; + ccomma.append_expression (new CCodeAssignment (lhs, cexpr)); } - clist.append (cexpr); + ccomma.append_expression (instance); + list.ccodenode = ccomma; } - - list.ccodenode = clist; } else { var clist = new CCodeInitializerList (); foreach (Expression expr in list.get_initializers ()) { diff --git a/tests/Makefile.am b/tests/Makefile.am index 0e995df87..8c83e86f7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -33,6 +33,7 @@ TESTS = \ enums/enums.vala \ structs/structs.vala \ structs/gvalue.vala \ + structs/bug583603.vala \ structs/bug595587.vala \ delegates/delegates.vala \ delegates/bug595639.vala \ diff --git a/tests/structs/bug583603.vala b/tests/structs/bug583603.vala new file mode 100644 index 000000000..9372ea910 --- /dev/null +++ b/tests/structs/bug583603.vala @@ -0,0 +1,9 @@ +struct Foo { + int bar; +} + +void main() { + int i = 42; + Foo foo = { i }; + assert (foo.bar == 42); +}