]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Fix non-constant struct initializer lists
authorJürg Billeter <j@bitron.ch>
Sun, 27 Sep 2009 08:40:08 +0000 (10:40 +0200)
committerJürg Billeter <j@bitron.ch>
Sun, 27 Sep 2009 08:49:31 +0000 (10:49 +0200)
Fixes bug 583603.

codegen/valaccodebasemodule.vala
tests/Makefile.am
tests/structs/bug583603.vala [new file with mode: 0644]

index a00bd242131eba3a23060b5ec371356ee1b62471..d20c8fac0a7d0f6817136133d7a533835014bfeb 100644 (file)
@@ -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 ()) {
index 0e995df87cc838b3bd603e59969d0a463ed5feac..8c83e86f78986a96ccd140b5d20bca6b27736954 100644 (file)
@@ -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 (file)
index 0000000..9372ea9
--- /dev/null
@@ -0,0 +1,9 @@
+struct Foo {
+       int bar;
+}
+
+void main() {
+       int i = 42;
+       Foo foo = { i };
+       assert (foo.bar == 42);
+}