diff --git a/dmd/declaration.c b/dmd/declaration.c index ab75eeaa..59efda0e 100644 --- a/dmd/declaration.c +++ b/dmd/declaration.c @@ -1408,4 +1408,13 @@ Dsymbol *ThisDeclaration::syntaxCopy(Dsymbol *s) return NULL; } +/********************** StaticStructInitDeclaration ***************************/ + +StaticStructInitDeclaration::StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym) + : Declaration(new Identifier("", TOKidentifier)) +{ + this->loc = loc; + this->dsym = dsym; + storage_class |= STCconst; +} diff --git a/dmd/declaration.h b/dmd/declaration.h index c8000214..b865d450 100644 --- a/dmd/declaration.h +++ b/dmd/declaration.h @@ -278,19 +278,18 @@ struct VarDeclaration : Declaration /**************************************************************/ -// This is a shell around a back end symbol +// LDC uses this to denote static struct initializers -struct SymbolDeclaration : Declaration +struct StaticStructInitDeclaration : Declaration { - Symbol *sym; StructDeclaration *dsym; - SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym); + StaticStructInitDeclaration(Loc loc, StructDeclaration *dsym); Symbol *toSymbol(); // Eliminate need for dynamic_cast - SymbolDeclaration *isSymbolDeclaration() { return (SymbolDeclaration *)this; } + StaticStructInitDeclaration *isStaticStructInitDeclaration() { return (StaticStructInitDeclaration *)this; } }; struct ClassInfoDeclaration : VarDeclaration diff --git a/dmd/dsymbol.h b/dmd/dsymbol.h index 75639c25..2f11fce0 100644 --- a/dmd/dsymbol.h +++ b/dmd/dsymbol.h @@ -65,7 +65,7 @@ struct EnumMember; struct ScopeDsymbol; struct WithScopeSymbol; struct ArrayScopeSymbol; -struct SymbolDeclaration; +struct StaticStructInitDeclaration; struct Expression; struct DeleteDeclaration; struct HdrGenState; @@ -216,7 +216,7 @@ struct Dsymbol : Object #ifdef _DH virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; } #endif - virtual SymbolDeclaration *isSymbolDeclaration() { return NULL; } + virtual StaticStructInitDeclaration *isStaticStructInitDeclaration() { return NULL; } virtual AttribDeclaration *isAttribDeclaration() { return NULL; } virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; } virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; } diff --git a/dmd/interpret.c b/dmd/interpret.c index f3404359..9a6ff47e 100644 --- a/dmd/interpret.c +++ b/dmd/interpret.c @@ -987,7 +987,7 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) { Expression *e = EXP_CANT_INTERPRET; VarDeclaration *v = d->isVarDeclaration(); - SymbolDeclaration *s = d->isSymbolDeclaration(); + StaticStructInitDeclaration *s = d->isStaticStructInitDeclaration(); if (v) { #if DMDV2 @@ -1011,11 +1011,9 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d) } else if (s) { - if (s->dsym->toInitializer() == s->sym) - { Expressions *exps = new Expressions(); - e = new StructLiteralExp(0, s->dsym, exps); - e = e->semantic(NULL); - } + Expressions *exps = new Expressions(); + e = new StructLiteralExp(0, s->dsym, exps); + e = e->semantic(NULL); } return e; } @@ -1466,10 +1464,10 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post) if (v->value && v->value->op == TOKvar) { VarExp *ve2 = (VarExp *)v->value; - if (ve2->var->isSymbolDeclaration()) + if (ve2->var->isStaticStructInitDeclaration()) { /* This can happen if v is a struct initialized to - * 0 using an __initZ SymbolDeclaration from + * 0 using an StaticStructInitDeclaration from * TypeStruct::defaultInit() */ } diff --git a/dmd/mtype.c b/dmd/mtype.c index 3660348f..c6b972b0 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -4584,14 +4584,12 @@ unsigned TypeStruct::memalign(unsigned salign) } Expression *TypeStruct::defaultInit(Loc loc) -{ Symbol *s; - Declaration *d; +{ Declaration *d; #if LOGDEFAULTINIT printf("TypeStruct::defaultInit() '%s'\n", toChars()); #endif - s = sym->toInitializer(); - d = new SymbolDeclaration(sym->loc, s, sym); + d = new StaticStructInitDeclaration(sym->loc, sym); assert(d); d->type = this; return new VarExp(sym->loc, d); diff --git a/gen/tocsym.cpp b/gen/tocsym.cpp index 508b1292..8a12d782 100644 --- a/gen/tocsym.cpp +++ b/gen/tocsym.cpp @@ -22,16 +22,10 @@ #include "attrib.h" #include "lexer.h" -/********************************* SymbolDeclaration ****************************/ -SymbolDeclaration::SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym) - : Declaration(new Identifier("", TOKidentifier)) +Symbol *StaticStructInitDeclaration::toSymbol() { -} - -Symbol *SymbolDeclaration::toSymbol() -{ - return sym; + return 0; } /************************************* diff --git a/gen/toir.cpp b/gen/toir.cpp index 54dac060..88e70c8a 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -179,7 +179,7 @@ DValue* VarExp::toElem(IRState* p) } return new DFuncValue(fdecl, func); } - else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) + else if (StaticStructInitDeclaration* sdecl = var->isStaticStructInitDeclaration()) { // this seems to be the static initialiser for structs Type* sdecltype = sdecl->type->toBasetype(); @@ -205,7 +205,7 @@ LLConstant* VarExp::toConstElem(IRState* p) { Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; - if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) + if (StaticStructInitDeclaration* sdecl = var->isStaticStructInitDeclaration()) { // this seems to be the static initialiser for structs Type* sdecltype = sdecl->type->toBasetype(); diff --git a/tests/mini/bug198_ctfestructinit.d b/tests/mini/bug198_ctfestructinit.d new file mode 100644 index 00000000..63828a7b --- /dev/null +++ b/tests/mini/bug198_ctfestructinit.d @@ -0,0 +1,12 @@ +struct Color { + uint c; + static Color opCall(uint _c) { Color ret; ret.c = _c; return ret; } +} + +// run at compile time +static const Color white = Color(0xffffffff); + +void main() +{ + assert(white.c == 0xffffffff); +} diff --git a/tests/mini/bug199_ctfestructinit.d b/tests/mini/bug199_ctfestructinit.d new file mode 100644 index 00000000..7e9ee2b4 --- /dev/null +++ b/tests/mini/bug199_ctfestructinit.d @@ -0,0 +1,25 @@ +struct Color { + uint c; + +} + +struct Vertex { + double x, y; + Color c; + static Vertex opCall(double x, double y, Color c) { + Vertex ret; + ret.x = x; + ret.y = y; + ret.c = c; + return ret; + } +} + +void main() { + Color c = {0xffffffff}; + + auto v = Vertex(1, 5, c); + + assert(v.x == 1 && v.y == 5); // passes + assert(v.c.c == 0xffffffff); // fails in LDC +} \ No newline at end of file