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(-)
This commit is contained in:
Leandro Lucarella
2010-01-06 15:18:23 -03:00
parent e7323517b0
commit 003f306cba
4 changed files with 55 additions and 31 deletions

View File

@@ -3264,9 +3264,7 @@ Expression *StructLiteralExp::semantic(Scope *sc)
}
}
else
{ e = v->type->defaultInit();
e->loc = loc;
}
e = v->type->defaultInitLiteral(loc);
offset = v->offset + v->type->size();
}
elements->push(e);

View File

@@ -1515,24 +1515,6 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Type *type,
}
/********************************
* 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.
*/
@@ -1592,7 +1574,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
}
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 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
*/
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 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
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 @@ Expression *DotVarExp::interpret(InterState *istate)
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

View File

@@ -569,12 +569,9 @@ int Type::checkBoolean()
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 @@ Expression *Type::defaultInit(Loc loc)
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 @@ Expression *TypeStruct::defaultInit(Loc loc)
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;

View File

@@ -250,6 +250,7 @@ struct Type : Object
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 @@ struct TypeStruct : Type
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