diff dmd/CommaExp.d @ 179:cd48cb899aee

Updated to dmd2.040
author korDen
date Sun, 17 Oct 2010 20:56:07 +0400
parents e3afd1303184
children b0d41ff5e0df
line wrap: on
line diff
--- a/dmd/CommaExp.d	Sun Oct 17 07:42:00 2010 +0400
+++ b/dmd/CommaExp.d	Sun Oct 17 20:56:07 2010 +0400
@@ -6,6 +6,9 @@
 import dmd.IRState;
 import dmd.Scope;
 import dmd.IntRange;
+import dmd.DeclarationExp;
+import dmd.VarExp;
+import dmd.VarDeclaration;
 import dmd.Expression;
 import dmd.GlobalExpressions;
 import dmd.MATCH;
@@ -113,6 +116,23 @@
 		Expression e;
 
 		//printf("CommaExp.optimize(result = %d) %s\n", result, toChars());
+		// Comma needs special treatment, because it may
+		// contain compiler-generated declarations. We can interpret them, but
+		// otherwise we must NOT attempt to constant-fold them.
+		// In particular, if the comma returns a temporary variable, it needs
+		// to be an lvalue (this is particularly important for struct constructors)
+
+		if (result & WANTinterpret)
+		{   
+			// Interpreting comma needs special treatment, because it may
+			// contain compiler-generated declarations.
+			e = interpret(null);
+			return (e is EXP_CANT_INTERPRET) ? this : e;
+		}
+		// Don't constant fold if it is a compiler-generated temporary.
+		if (e1.op == TOKdeclaration)
+		   return this;
+
 		e1 = e1.optimize(result & WANTinterpret);
 		e2 = e2.optimize(result);
 		if (!e1 || e1.op == TOKint64 || e1.op == TOKfloat64 || !e1.checkSideEffect(2))
@@ -132,6 +152,21 @@
 version (LOG) {
 		printf("CommaExp.interpret() %.*s\n", toChars());
 }
+		// If the comma returns a temporary variable, it needs to be an lvalue
+		// (this is particularly important for struct constructors)
+		if (e1.op == TOKdeclaration && e2.op == TOKvar 
+		   && (cast(DeclarationExp)e1).declaration == (cast(VarExp)e2).var)
+		{
+			VarExp ve = cast(VarExp)e2;
+			VarDeclaration v = ve.var.isVarDeclaration();
+			if (!v.init && !v.value)
+				v.value = v.type.defaultInitLiteral(Loc(0));
+			if (!v.value)
+				v.value = v.init.toExpression();
+			v.value = v.value.interpret(istate);	
+			return e2;
+		}
+
 		Expression e = e1.interpret(istate);
 		if (e !is EXP_CANT_INTERPRET)
 			e = e2.interpret(istate);