[vala] Fix non-constant struct initializer lists



commit 5b59b98fb4bba4726373e4c9372f03cd459d207b
Author: Jürg Billeter <j bitron ch>
Date:   Sun Sep 27 10:40:08 2009 +0200

    Fix non-constant struct initializer lists
    
    Fixes bug 583603.

 codegen/valaccodebasemodule.vala |   70 ++++++++++++++++++++++++++++---------
 tests/Makefile.am                |    1 +
 tests/structs/bug583603.vala     |    9 +++++
 3 files changed, 63 insertions(+), 17 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index a00bd24..d20c8fa 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 0e995df..8c83e86 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 0000000..9372ea9
--- /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);
+}



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