mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-14 11:53:13 +01:00
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:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
48
dmd/mtype.c
48
dmd/mtype.c
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user