changeset 1627:e83f0778c260

Merge DMD r321: bugzilla 3575 CTFE: member structs not initialized correctly --- dmd/expression.c | 4 +--- dmd/interpret.c | 32 +++++++++----------------------- dmd/mtype.c | 48 +++++++++++++++++++++++++++++++++++++++++++----- dmd/mtype.h | 2 ++ 4 files changed, 55 insertions(+), 31 deletions(-)
author Leandro Lucarella <llucax@gmail.com>
date Wed, 06 Jan 2010 15:18:23 -0300
parents 8fa4ab3dcc88
children 6c36e3f49b28
files dmd/expression.c dmd/interpret.c dmd/mtype.c dmd/mtype.h
diffstat 4 files changed, 55 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/expression.c	Wed Jan 06 15:18:23 2010 -0300
+++ b/dmd/expression.c	Wed Jan 06 15:18:23 2010 -0300
@@ -3264,9 +3264,7 @@
 		}
 	    }
 	    else
-	    {	e = v->type->defaultInit();
-		e->loc = loc;
-	    }
+		e = v->type->defaultInitLiteral(loc);
 	    offset = v->offset + v->type->size();
 	}
 	elements->push(e);
--- a/dmd/interpret.c	Wed Jan 06 15:18:23 2010 -0300
+++ b/dmd/interpret.c	Wed Jan 06 15:18:23 2010 -0300
@@ -1516,24 +1516,6 @@
 
 
 /********************************
- * Necessary because defaultInit() for a struct is a VarExp, not a StructLiteralExp.
- */
-StructLiteralExp *createDefaultInitStructLiteral(Loc loc, StructDeclaration *sym)
-{
-    Expressions *structelems = new Expressions();
-    structelems->setDim(sym->fields.dim);
-    for (size_t j = 0; j < structelems->dim; j++)
-    {
-	structelems->data[j] = ((VarDeclaration *)(sym->fields.data[j]))->type->defaultInit();
-    }
-    StructLiteralExp *structinit = new StructLiteralExp(loc, sym, structelems);
-    // Why doesn't the StructLiteralExp constructor do this, when
-    // sym->type != NULL ?
-    structinit->type = sym->type;
-    return structinit;
-}
-
-/********************************
  *  Add v to the istate list, unless it already exists there.
  */
 void addVarToInterstate(InterState *istate, VarDeclaration *v)
@@ -1592,7 +1574,7 @@
 	}
 	else if (v && v->value && (v->value->op==TOKindex || v->value->op == TOKdotvar))
 	{
-            // It is no longer be a TOKvar, eg when a[4] is passed by ref.
+            // It is no longer a TOKvar, eg when a[4] is passed by ref.
 	    e1 = v->value;	    
 	}
     }
@@ -1634,7 +1616,7 @@
 		 */
 		if (v->type->toBasetype()->ty == Tstruct && e2->op == TOKint64)
 		{
-		    e2 = v->type->defaultInit();
+		    e2 = v->type->defaultInitLiteral();
 		}
 		e2 = Cast(v->type, v->type, e2);
 	    }
@@ -1960,8 +1942,7 @@
 	    if (telem->ty != Tstruct) { return EXP_CANT_INTERPRET; }
 
 	    // Create a default struct literal...
-	    StructDeclaration *sym = ((TypeStruct *)telem)->sym;
-	    StructLiteralExp *structinit = createDefaultInitStructLiteral(v->loc, sym);
+	    Expression *structinit = telem->defaultInitLiteral(v->loc);
 
 	    // ... and use to create a blank array literal
 	    size_t dim = ((TypeSArray *)t)->dim->toInteger();
@@ -2642,10 +2623,15 @@
 	    if (v)
 	    {	e = se->getField(type, v->offset);
 		if (!e)
+		{
+		    error("couldn't find field %s in %s", v->toChars(), type->toChars());
 		    e = EXP_CANT_INTERPRET;
+		}
 		return e;
 	    }
-	} else error("%s.%s is not yet implemented at compile time", ex->toChars(), var->toChars());
+	}
+	else
+	    error("%s.%s is not yet implemented at compile time", ex->toChars(), var->toChars());
     }
 
 #if LOG
--- a/dmd/mtype.c	Wed Jan 06 15:18:23 2010 -0300
+++ b/dmd/mtype.c	Wed Jan 06 15:18:23 2010 -0300
@@ -569,12 +569,9 @@
 
 void Type::checkDeprecated(Loc loc, Scope *sc)
 {
-    Type *t;
-    Dsymbol *s;
-
-    for (t = this; t; t = t->next)
+    for (Type *t = this; t; t = t->next)
     {
-	s = t->toDsymbol(sc);
+	Dsymbol *s = t->toDsymbol(sc);
 	if (s)
 	    s->checkDeprecated(loc, sc);
     }
@@ -589,6 +586,18 @@
     return NULL;
 }
 
+/***************************************
+ * Use when we prefer the default initializer to be a literal,
+ * rather than a global immutable variable.
+ */
+Expression *Type::defaultInitLiteral(Loc loc)
+{
+#if LOGDEFAULTINIT
+    printf("Type::defaultInitLiteral() '%s'\n", toChars());
+#endif
+    return defaultInit(loc);
+}
+
 int Type::isZeroInit(Loc loc)
 {
     return 0;		// assume not
@@ -4707,6 +4716,35 @@
     return new VarExp(sym->loc, d);
 }
 
+/***************************************
+ * Use when we prefer the default initializer to be a literal,
+ * rather than a global immutable variable.
+ */
+Expression *TypeStruct::defaultInitLiteral(Loc loc)
+{
+#if LOGDEFAULTINIT
+    printf("TypeStruct::defaultInitLiteral() '%s'\n", toChars());
+#endif
+    Expressions *structelems = new Expressions();
+    structelems->setDim(sym->fields.dim);
+    for (size_t j = 0; j < structelems->dim; j++)
+    {
+	VarDeclaration *vd = (VarDeclaration *)(sym->fields.data[j]);
+	Expression *e;
+	if (vd->init)
+	    e = vd->init->toExpression();
+	else
+	    e = vd->type->defaultInitLiteral();
+	structelems->data[j] = e;
+    }
+    StructLiteralExp *structinit = new StructLiteralExp(loc, (StructDeclaration *)sym, structelems);
+    // Why doesn't the StructLiteralExp constructor do this, when
+    // sym->type != NULL ?
+    structinit->type = sym->type;
+    return structinit;
+}
+
+
 int TypeStruct::isZeroInit(Loc loc)
 {
     return sym->zeroInit;
--- a/dmd/mtype.h	Wed Jan 06 15:18:23 2010 -0300
+++ b/dmd/mtype.h	Wed Jan 06 15:18:23 2010 -0300
@@ -250,6 +250,7 @@
     virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
     virtual unsigned memalign(unsigned salign);
     virtual Expression *defaultInit(Loc loc = 0);
+    virtual Expression *defaultInitLiteral(Loc loc = 0);
     virtual int isZeroInit(Loc loc = 0);		// if initializer is 0
 #if IN_DMD
     virtual dt_t **toDt(dt_t **pdt);
@@ -582,6 +583,7 @@
     Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
     unsigned memalign(unsigned salign);
     Expression *defaultInit(Loc loc);
+    Expression *defaultInitLiteral(Loc loc);
     int isZeroInit(Loc loc);
     int checkBoolean();
 #if IN_DMD