From 5fed9e61acaca03822dd871372ebf6cfe19df989 Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Thu, 14 Aug 2014 18:39:32 -0700 Subject: [PATCH] Merge pull request #3822 from 9rnsr/fix13204 Issue 13204 - recursive alias declaration --- src/declaration.c | 34 ++++++++++++++++++++++++---------- src/declaration.h | 2 +- src/mtype.c | 9 +++++---- test/runnable/template9.d | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/declaration.c b/src/declaration.c index a8d935460c86..078e34fe5088 100644 --- a/src/declaration.c +++ b/src/declaration.c @@ -429,7 +429,7 @@ AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Type *type) this->htype = NULL; this->haliassym = NULL; this->overnext = NULL; - this->inSemantic = false; + this->inSemantic = 0; assert(type); } @@ -445,7 +445,7 @@ AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s) this->htype = NULL; this->haliassym = NULL; this->overnext = NULL; - this->inSemantic = false; + this->inSemantic = 0; assert(s); } @@ -490,7 +490,7 @@ void AliasDeclaration::semantic(Scope *sc) aliassym->semantic(sc); return; } - this->inSemantic = true; + this->inSemantic = 1; storage_class |= sc->stc & STCdeprecated; protection = sc->protection; @@ -570,7 +570,7 @@ void AliasDeclaration::semantic(Scope *sc) } if (overnext) ScopeDsymbol::multiplyDefined(Loc(), overnext, this); - this->inSemantic = false; + this->inSemantic = 0; if (global.gag && errors != global.errors) type = savedtype; @@ -646,14 +646,12 @@ void AliasDeclaration::semantic(Scope *sc) { type = savedtype; overnext = savedovernext; - aliassym = NULL; - inSemantic = false; - return; + s = NULL; } } //printf("setting aliassym %s to %s %s\n", toChars(), s->kind(), s->toChars()); aliassym = s; - this->inSemantic = false; + this->inSemantic = 0; } bool AliasDeclaration::overloadInsert(Dsymbol *s) @@ -712,10 +710,26 @@ Dsymbol *AliasDeclaration::toAlias() //printf("AliasDeclaration::toAlias('%s', this = %p, aliassym = %p, kind = '%s')\n", toChars(), this, aliassym, aliassym ? aliassym->kind() : ""); assert(this != aliassym); //static int count; if (++count == 10) *(char*)0=0; + if (inSemantic == 1 && type && scope) + { + inSemantic = 2; + unsigned olderrors = global.errors; + Dsymbol *s = type->toDsymbol(scope); + //printf("[%s] %s, s = %p, this = %p\n", loc.toChars(), type->toChars(), s, this); + if (!s || global.errors != olderrors) + goto Lerr; + s = s->toAlias(); + if (global.errors != olderrors) + goto Lerr; + + aliassym = s; + inSemantic = 0; + } if (inSemantic) { error("recursive alias declaration"); + Lerr: // Avoid breaking "recursive alias" state during errors gagged if (global.isSpeculativeGagging()) return this; @@ -736,9 +750,9 @@ Dsymbol *AliasDeclaration::toAlias() } else if (scope) semantic(scope); - inSemantic = true; + inSemantic = 1; Dsymbol *s = aliassym ? aliassym->toAlias() : this; - inSemantic = false; + inSemantic = 0; return s; } diff --git a/src/declaration.h b/src/declaration.h index 150c7143367b..f899d498a2ed 100644 --- a/src/declaration.h +++ b/src/declaration.h @@ -223,7 +223,7 @@ class AliasDeclaration : public Declaration Dsymbol *aliassym; Dsymbol *overnext; // next in overload list Dsymbol *import; // !=NULL if unresolved internal alias for selective import - bool inSemantic; + int inSemantic; AliasDeclaration(Loc loc, Identifier *ident, Type *type); AliasDeclaration(Loc loc, Identifier *ident, Dsymbol *s); diff --git a/src/mtype.c b/src/mtype.c index 40e009414b13..edafa663d6b8 100644 --- a/src/mtype.c +++ b/src/mtype.c @@ -6842,7 +6842,8 @@ Dsymbol *TypeIdentifier::toDsymbol(Scope *sc) RootObject *id = idents[i]; s = s->searchX(loc, sc, id); if (!s) // failed to find a symbol - { //printf("\tdidn't find a symbol\n"); + { + //printf("\tdidn't find a symbol\n"); break; } } @@ -7001,6 +7002,8 @@ Dsymbol *TypeInstance::toDsymbol(Scope *sc) //printf("TypeInstance::semantic(%s)\n", toChars()); resolve(loc, sc, &e, &t, &s); + if (t && t->ty != Tinstance) + s = t->toDsymbol(sc); return s; } @@ -7055,9 +7058,7 @@ Type *TypeTypeof::syntaxCopy() Dsymbol *TypeTypeof::toDsymbol(Scope *sc) { - Type *t; - - t = semantic(loc, sc); + Type *t = semantic(loc, sc); if (t == this) return NULL; return t->toDsymbol(sc); diff --git a/test/runnable/template9.d b/test/runnable/template9.d index 2ce8019ad8f4..a53a64b20671 100644 --- a/test/runnable/template9.d +++ b/test/runnable/template9.d @@ -3766,6 +3766,38 @@ void test13180() string s2b = get2b(def, aa); } +/******************************************/ +// 13204 + +struct A13204(uint v) +{ + alias whatever = A13204y; + static assert(is(whatever == A13204)); +} +alias A13204x = A13204!1; +alias A13204y = A13204x; + +struct B13204(uint v) +{ + alias whatever = B13204z; + static assert(is(whatever == B13204)); +} +alias B13204x = B13204!1; +alias B13204y = B13204x; +alias B13204z = B13204y; + +void test13204() +{ + static assert(is(A13204x == A13204!1)); + static assert(is(A13204x == A13204!1.whatever)); + static assert(is(A13204x == A13204y)); + + static assert(is(B13204x == B13204!1)); + static assert(is(B13204x == B13204!1.whatever)); + static assert(is(B13204x == B13204y)); + static assert(is(B13204x == B13204z)); +} + /******************************************/ // 13218