From patchwork Sun Jun 16 22:50:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1116663 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-503041-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=gdcproject.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45RqMR3TWhz9s00 for ; Mon, 17 Jun 2019 08:51:06 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; q= dns; s=default; b=ucO++RyD0pMepppcq5a3LiPg6jpb6s271ZOh3sxXQFuyuE IesFng4EUoxhTut1xnwujQl2ISQhtDjVOTUXZcBMqG0H+oBeoBsFWA1MAZ9Nn1bL piQM4ZCdw74uoObaGE7HIsQI1do1HcU874EIf5K1E9EVxwJDyLnVb/NJmnMz8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :mime-version:from:date:message-id:subject:to:content-type; s= default; bh=czWTiJr5SFGne1Bb/hl8J/0w1fE=; b=qJpbV7SMQRRcZaHD7Gr+ 4DspkFTpeP0HaPj3UIGky5fGxoq2Ly+kei97/GjI1EyCsJdJPskDdJYZYMGohUGs hYP2MSViYTCQme0TNeWFP76dwCNDFhwXN2/T678uuR19bLagBSjYwY3rCpRSEZbr 4RP5bZgyxBwkb1dY/9UaTew= Received: (qmail 114188 invoked by alias); 16 Jun 2019 22:50:57 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 114081 invoked by uid 89); 16 Jun 2019 22:50:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.2 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=ft X-HELO: mail-qk1-f171.google.com Received: from mail-qk1-f171.google.com (HELO mail-qk1-f171.google.com) (209.85.222.171) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 16 Jun 2019 22:50:51 +0000 Received: by mail-qk1-f171.google.com with SMTP id c70so5107300qkg.7 for ; Sun, 16 Jun 2019 15:50:50 -0700 (PDT) MIME-Version: 1.0 From: Iain Buclaw Date: Mon, 17 Jun 2019 00:50:37 +0200 Message-ID: Subject: [PATCH, PR d/90603] Committed fix for ICE in functionParameters To: gcc-patches X-IsSubscribed: yes Hi, This patch merges the dmd frontend implementation with upstream dmd 792f0fdf2. Backports semantic pass refactoring, fixing a number of ICEs in handling forward or recursively referenced declarations. Bootstrapped and regression tested on x86_64-linux-gnu. Committed to trunk as r272366 diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 0620a5ba556..d208aea3717 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -6e44734ccbeb78252a52e129a67fefb313679948 +792f0fdf249b21531dc91690024827f4f9ecbb97 The first line of this file holds the git revision number of the last merge done from the dlang/dmd repository. diff --git a/gcc/d/dmd/dclass.c b/gcc/d/dmd/dclass.c index 572b3e24387..bbe2f8a9d72 100644 --- a/gcc/d/dmd/dclass.c +++ b/gcc/d/dmd/dclass.c @@ -481,7 +481,7 @@ void ClassDeclaration::semantic(Scope *sc) baseClass = tc->sym; b->sym = baseClass; - if (tc->sym->_scope && tc->sym->baseok < BASEOKdone) + if (tc->sym->baseok < BASEOKdone) resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference if (tc->sym->baseok < BASEOKdone) { @@ -533,7 +533,7 @@ void ClassDeclaration::semantic(Scope *sc) b->sym = tc->sym; - if (tc->sym->_scope && tc->sym->baseok < BASEOKdone) + if (tc->sym->baseok < BASEOKdone) resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference if (tc->sym->baseok < BASEOKdone) { @@ -918,10 +918,10 @@ bool ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset) { /* cd->baseClass might not be set if cd is forward referenced. */ - if (!cd->baseClass && cd->_scope && !cd->isInterfaceDeclaration()) + if (!cd->baseClass && cd->semanticRun < PASSsemanticdone && !cd->isInterfaceDeclaration()) { cd->semantic(NULL); - if (!cd->baseClass && cd->_scope) + if (!cd->baseClass && cd->semanticRun < PASSsemanticdone) cd->error("base class is forward referenced by %s", toChars()); } @@ -1574,7 +1574,7 @@ void InterfaceDeclaration::semantic(Scope *sc) b->sym = tc->sym; - if (tc->sym->_scope && tc->sym->baseok < BASEOKdone) + if (tc->sym->baseok < BASEOKdone) resolveBase(this, sc, scx, tc->sym); // Try to resolve forward reference if (tc->sym->baseok < BASEOKdone) { diff --git a/gcc/d/dmd/declaration.c b/gcc/d/dmd/declaration.c index 2a054306347..0018d9501f0 100644 --- a/gcc/d/dmd/declaration.c +++ b/gcc/d/dmd/declaration.c @@ -865,6 +865,11 @@ void VarDeclaration::semantic(Scope *sc) _scope = NULL; } + if (!sc) + return; + + semanticRun = PASSsemantic; + /* Pick up storage classes from context, but except synchronized, * override, abstract, and final. */ @@ -1038,6 +1043,7 @@ void VarDeclaration::semantic(Scope *sc) else if (isAliasThisTuple(e)) { VarDeclaration *v = copyToTemp(0, "__tup", e); + v->semantic(sc); VarExp *ve = new VarExp(loc, v); ve->type = e->type; @@ -1439,7 +1445,7 @@ Lnomatch: if (!e) { error("is not a static and cannot have static initializer"); - return; + e = new ErrorExp(); } } ei = new ExpInitializer(_init->loc, e); diff --git a/gcc/d/dmd/denum.c b/gcc/d/dmd/denum.c index fbca54b7dae..ff261bc0ad0 100644 --- a/gcc/d/dmd/denum.c +++ b/gcc/d/dmd/denum.c @@ -110,6 +110,9 @@ void EnumDeclaration::semantic(Scope *sc) _scope = NULL; } + if (!sc) + return; + parent = sc->parent; type = type->semantic(loc, sc); diff --git a/gcc/d/dmd/dimport.c b/gcc/d/dmd/dimport.c index 3d899f09b52..5f7d7fdc09e 100644 --- a/gcc/d/dmd/dimport.c +++ b/gcc/d/dmd/dimport.c @@ -197,12 +197,18 @@ void Import::importAll(Scope *sc) void Import::semantic(Scope *sc) { //printf("Import::semantic('%s') %s\n", toPrettyChars(), id->toChars()); + if (semanticRun > PASSinit) + return; if (_scope) { sc = _scope; _scope = NULL; } + if (!sc) + return; + + semanticRun = PASSsemantic; // Load if not already done so if (!mod) @@ -291,6 +297,8 @@ void Import::semantic(Scope *sc) sc = sc->pop(); } + semanticRun = PASSsemanticdone; + // object self-imports itself, so skip that (Bugzilla 7547) // don't list pseudo modules __entrypoint.d, __main.d (Bugzilla 11117, 11164) if (global.params.moduleDeps != NULL && diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c index 0749c7f487d..a1658bbd051 100644 --- a/gcc/d/dmd/dinterpret.c +++ b/gcc/d/dmd/dinterpret.c @@ -2085,9 +2085,9 @@ public: if (v->ident == Id::ctfe) return new IntegerExp(loc, 1, Type::tbool); - if (!v->originalType && v->_scope) // semantic() not yet run + if (!v->originalType && v->semanticRun < PASSsemanticdone) // semantic() not yet run { - v->semantic (v->_scope); + v->semantic(NULL); if (v->type->ty == Terror) return CTFEExp::cantexp; } diff --git a/gcc/d/dmd/dstruct.c b/gcc/d/dmd/dstruct.c index 1338e1f69b0..22da0a3be3d 100644 --- a/gcc/d/dmd/dstruct.c +++ b/gcc/d/dmd/dstruct.c @@ -116,7 +116,7 @@ void semanticTypeInfo(Scope *sc, Type *t) // Bugzilla 15149, if the typeid operand type comes from a // result of auto function, it may be yet speculative. - unSpeculative(sc, sd); + // unSpeculative(sc, sd); } /* Step 2: If the TypeInfo generation requires sd.semantic3, run it later. @@ -324,6 +324,7 @@ void AggregateDeclaration::semantic3(Scope *sc) if (sd) sd->semanticTypeInfoMembers(); + semanticRun = PASSsemantic3done; } /*************************************** @@ -359,7 +360,7 @@ bool AggregateDeclaration::determineFields() AggregateDeclaration *ad = ((SV *)param)->agg; - if (v->_scope) + if (v->semanticRun < PASSsemanticdone) v->semantic(NULL); // Note: Aggregate fields or size could have determined during v->semantic. if (ad->sizeok != SIZEOKnone) diff --git a/gcc/d/dmd/dtemplate.c b/gcc/d/dmd/dtemplate.c index 0173ee401b6..b5e3662a9e3 100644 --- a/gcc/d/dmd/dtemplate.c +++ b/gcc/d/dmd/dtemplate.c @@ -685,6 +685,7 @@ void TemplateDeclaration::semantic(Scope *sc) /* BUG: should check: * o no virtual functions or non-static data members of classes */ + semanticRun = PASSsemanticdone; } const char *TemplateDeclaration::kind() const @@ -2169,12 +2170,14 @@ void functionResolve(Match *m, Dsymbol *dstart, Loc loc, Scope *sc, if (tiargs && tiargs->dim > 0) return 0; - if (fd->semanticRun == PASSinit && fd->_scope) + // constructors need a valid scope in order to detect semantic errors + if (!fd->isCtorDeclaration() && + fd->semanticRun < PASSsemanticdone) { Ungag ungag = fd->ungagSpeculative(); - fd->semantic(fd->_scope); + fd->semantic(NULL); } - if (fd->semanticRun == PASSinit) + if (fd->semanticRun < PASSsemanticdone) { ::error(loc, "forward reference to template %s", fd->toChars()); return 1; diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c index af762eb3c66..c674392095e 100644 --- a/gcc/d/dmd/expression.c +++ b/gcc/d/dmd/expression.c @@ -516,9 +516,9 @@ static bool checkPropertyCall(Expression *e) tf = (TypeFunction *)ce->f->type; /* If a forward reference to ce->f, try to resolve it */ - if (!tf->deco && ce->f->_scope) + if (!tf->deco && ce->f->semanticRun < PASSsemanticdone) { - ce->f->semantic(ce->f->_scope); + ce->f->semantic(NULL); tf = (TypeFunction *)ce->f->type; } } @@ -1125,6 +1125,8 @@ bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt) Type *t0 = NULL; Expression *e0 = NULL; // dead-store to prevent spurious warning size_t j0 = ~0; // dead-store to prevent spurious warning + bool foundType = false; + for (size_t i = 0; i < exps->dim; i++) { Expression *e = (*exps)[i]; @@ -1140,6 +1142,7 @@ bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt) } if (e->op == TOKtype) { + foundType = true; // do not break immediately, there might be more errors e->checkValue(); // report an error "type T has no value" t0 = Type::terror; continue; @@ -1158,7 +1161,7 @@ bool arrayExpressionToCommonType(Scope *sc, Expressions *exps, Type **pt) e = doCopyOrMove(sc, e); - if (t0 && !t0->equals(e->type)) + if (!foundType && t0 && !t0->equals(e->type)) { /* This applies ?: to merge the types. It's backwards; * ?: should call this function to merge types. diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c index 88c59a9045b..c23e332b180 100644 --- a/gcc/d/dmd/expressionsem.c +++ b/gcc/d/dmd/expressionsem.c @@ -397,6 +397,7 @@ public: // Create the magic __ctfe bool variable VarDeclaration *vd = new VarDeclaration(exp->loc, Type::tbool, Id::ctfe, NULL); vd->storage_class |= STCtemp; + vd->semanticRun = PASSsemanticdone; Expression *e = new VarExp(exp->loc, vd); e = semantic(e, sc); result = e; @@ -1441,7 +1442,10 @@ public: void visit(VarExp *e) { - if (FuncDeclaration *fd = e->var->isFuncDeclaration()) + VarDeclaration *vd = e->var->isVarDeclaration(); + FuncDeclaration *fd = e->var->isFuncDeclaration(); + + if (fd) { //printf("L%d fd = %s\n", __LINE__, f->toChars()); if (!fd->functionSemantic()) @@ -1452,7 +1456,14 @@ public: e->type = e->var->type; if (e->type && !e->type->deco) + { + Declaration *decl = e->var->isDeclaration(); + if (decl) + decl->inuse++; e->type = e->type->semantic(e->loc, sc); + if (decl) + decl->inuse--; + } /* Fix for 1161 doesn't work because it causes protection * problems when instantiating imported templates passing private @@ -1460,7 +1471,7 @@ public: */ //checkAccess(e->loc, sc, NULL, e->var); - if (VarDeclaration *vd = e->var->isVarDeclaration()) + if (vd) { if (vd->checkNestedReference(sc, e->loc)) return setError(); @@ -1468,7 +1479,7 @@ public: // the purity violation error is redundant. //checkPurity(sc, vd); } - else if (FuncDeclaration *fd = e->var->isFuncDeclaration()) + else if (fd) { // TODO: If fd isn't yet resolved its overload, the checkNestedReference // call would cause incorrect validation. @@ -1962,8 +1973,8 @@ public: ClassDeclaration *cd = ((TypeClass *)e->targ)->sym; Parameters *args = new Parameters; args->reserve(cd->baseclasses->dim); - if (cd->_scope && !cd->symtab) - cd->semantic(cd->_scope); + if (cd->semanticRun < PASSsemanticdone) + cd->semantic(NULL); for (size_t i = 0; i < cd->baseclasses->dim; i++) { BaseClass *b = (*cd->baseclasses)[i]; diff --git a/gcc/d/dmd/func.c b/gcc/d/dmd/func.c index 04c70cf3b7b..11e4b2f721b 100644 --- a/gcc/d/dmd/func.c +++ b/gcc/d/dmd/func.c @@ -471,6 +471,9 @@ void FuncDeclaration::semantic(Scope *sc) _scope = NULL; } + if (!sc || errors) + return; + parent = sc->parent; Dsymbol *parent = toParent(); @@ -932,6 +935,7 @@ void FuncDeclaration::semantic(Scope *sc) case -2: // can't determine because of forward references + errors = true; return; default: @@ -1049,6 +1053,7 @@ void FuncDeclaration::semantic(Scope *sc) case -2: // can't determine because of forward references + errors = true; return; default: diff --git a/gcc/d/dmd/mtype.c b/gcc/d/dmd/mtype.c index 906fb11b634..b76b5baad25 100644 --- a/gcc/d/dmd/mtype.c +++ b/gcc/d/dmd/mtype.c @@ -4672,7 +4672,7 @@ Type *TypeAArray::semantic(Loc loc, Scope *sc) /* AA's need typeid(index).equals() and getHash(). Issue error if not correctly set up. */ StructDeclaration *sd = ((TypeStruct *)tbase)->sym; - if (sd->_scope) + if (sd->semanticRun < PASSsemanticdone) sd->semantic(NULL); // duplicate a part of StructDeclaration::semanticTypeInfoMembers @@ -4739,7 +4739,7 @@ Type *TypeAArray::semantic(Loc loc, Scope *sc) else if (tbase->ty == Tclass && !((TypeClass *)tbase)->sym->isInterfaceDeclaration()) { ClassDeclaration *cd = ((TypeClass *)tbase)->sym; - if (cd->_scope) + if (cd->semanticRun < PASSsemanticdone) cd->semantic(NULL); if (!ClassDeclaration::object) @@ -5336,7 +5336,7 @@ int Type::covariant(Type *t, StorageClass *pstc, bool fix17349) // If t1n is forward referenced: ClassDeclaration *cd = ((TypeClass *)t1n)->sym; - if (cd->_scope) + if (cd->semanticRun < PASSsemanticdone && !cd->isBaseInfoComplete()) cd->semantic(NULL); if (!cd->isBaseInfoComplete()) { @@ -5448,6 +5448,13 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) bool errors = false; + if (inuse > 500) + { + inuse = 0; + ::error(loc, "recursive type"); + return Type::terror; + } + /* Copy in order to not mess up original. * This can produce redundant copies if inferring return type, * as semantic() will get called again on this. @@ -5532,9 +5539,9 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) for (size_t i = 0; i < dim; i++) { Parameter *fparam = Parameter::getNth(tf->parameters, i); - tf->inuse++; + inuse++; fparam->type = fparam->type->semantic(loc, argsc); - if (tf->inuse == 1) tf->inuse--; + inuse--; if (fparam->type->ty == Terror) { @@ -5776,13 +5783,6 @@ Type *TypeFunction::semantic(Loc loc, Scope *sc) } tf->iswild = wildparams; - if (tf->inuse) - { - error(loc, "recursive type"); - tf->inuse = 0; - errors = true; - } - if (tf->isproperty && (tf->varargs || Parameter::dim(tf->parameters) > 2)) { error(loc, "properties can only have zero, one, or two parameter"); @@ -7444,8 +7444,8 @@ Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident, int fl if (ident == Id::_mangleof) return getProperty(e->loc, ident, flag & 1); - if (sym->_scope) - sym->semantic(sym->_scope); + if (sym->semanticRun < PASSsemanticdone) + sym->semantic(NULL); if (!sym->members) { if (sym->isSpecial()) @@ -7914,8 +7914,8 @@ L1: return e; } } - if (d->semanticRun == PASSinit && d->_scope) - d->semantic(d->_scope); + if (d->semanticRun == PASSinit) + d->semantic(NULL); checkAccess(e->loc, sc, e, d); VarExp *ve = new VarExp(e->loc, d); if (d->isVarDeclaration() && d->needThis()) @@ -8443,7 +8443,7 @@ L1: if (ident == Id::outer && sym->vthis) { - if (sym->vthis->_scope) + if (sym->vthis->semanticRun == PASSinit) sym->vthis->semantic(NULL); if (ClassDeclaration *cdp = sym->toParent2()->isClassDeclaration()) @@ -8670,8 +8670,8 @@ L1: } } //printf("e = %s, d = %s\n", e->toChars(), d->toChars()); - if (d->semanticRun == PASSinit && d->_scope) - d->semantic(d->_scope); + if (d->semanticRun == PASSinit) + d->semantic(NULL); checkAccess(e->loc, sc, e, d); VarExp *ve = new VarExp(e->loc, d); if (d->isVarDeclaration() && d->needThis()) @@ -8727,9 +8727,9 @@ MATCH TypeClass::implicitConvTo(Type *to) if (cdto) { //printf("TypeClass::implicitConvTo(to = '%s') %s, isbase = %d %d\n", to->toChars(), toChars(), cdto->isBaseInfoComplete(), sym->isBaseInfoComplete()); - if (cdto->_scope && !cdto->isBaseInfoComplete()) + if (cdto->semanticRun < PASSsemanticdone && !cdto->isBaseInfoComplete()) cdto->semantic(NULL); - if (sym->_scope && !sym->isBaseInfoComplete()) + if (sym->semanticRun < PASSsemanticdone && !sym->isBaseInfoComplete()) sym->semantic(NULL); if (cdto->isBaseOf(sym, NULL) && MODimplicitConv(mod, to->mod)) { diff --git a/gcc/d/dmd/optimize.c b/gcc/d/dmd/optimize.c index b382d0adeb4..2e702ba9d86 100644 --- a/gcc/d/dmd/optimize.c +++ b/gcc/d/dmd/optimize.c @@ -34,8 +34,8 @@ Expression *expandVar(int result, VarDeclaration *v) Expression *e = NULL; if (!v) return e; - if (!v->originalType && v->_scope) // semantic() not yet run - v->semantic (v->_scope); + if (!v->originalType && v->semanticRun < PASSsemanticdone) // semantic() not yet run + v->semantic(NULL); if (v->isConst() || v->isImmutable() || v->storage_class & STCmanifest) { diff --git a/gcc/d/dmd/statement.c b/gcc/d/dmd/statement.c index 2d3a11237cb..450b3f4f594 100644 --- a/gcc/d/dmd/statement.c +++ b/gcc/d/dmd/statement.c @@ -1312,7 +1312,7 @@ Statement *OnScopeStatement::syntaxCopy() return new OnScopeStatement(loc, tok, statement->syntaxCopy()); } -Statement *OnScopeStatement::scopeCode(Scope *, Statement **sentry, Statement **sexception, Statement **sfinally) +Statement *OnScopeStatement::scopeCode(Scope *sc, Statement **sentry, Statement **sexception, Statement **sfinally) { //printf("OnScopeStatement::scopeCode()\n"); //print(); @@ -1340,6 +1340,7 @@ Statement *OnScopeStatement::scopeCode(Scope *, Statement **sentry, Statement ** * sfinally: if (!x) statement; */ VarDeclaration *v = copyToTemp(0, "__os", new IntegerExp(Loc(), 0, Type::tbool)); + v->semantic(sc); *sentry = new ExpStatement(loc, v); Expression *e = new IntegerExp(Loc(), 1, Type::tbool); diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c index 143864dc666..cc2b63e2466 100644 --- a/gcc/d/dmd/statementsem.c +++ b/gcc/d/dmd/statementsem.c @@ -1074,6 +1074,7 @@ public: else { r = copyToTemp(0, "__r", fs->aggr); + r->semantic(sc); init = new ExpStatement(loc, r); if (vinit) init = new CompoundStatement(loc, new ExpStatement(loc, vinit), init); @@ -1106,6 +1107,7 @@ public: else { VarDeclaration *vd = copyToTemp(STCref, "__front", einit); + vd->semantic(sc); makeargs = new ExpStatement(loc, vd); Type *tfront = NULL; @@ -2986,6 +2988,7 @@ public: * try { body } finally { _d_monitorexit(tmp); } */ VarDeclaration *tmp = copyToTemp(0, "__sync", ss->exp); + tmp->semantic(sc); Statements *cs = new Statements(); cs->push(new ExpStatement(ss->loc, tmp)); @@ -3133,6 +3136,7 @@ public: * } */ VarDeclaration *tmp = copyToTemp(0, "__withtmp", ws->exp); + tmp->semantic(sc); ExpStatement *es = new ExpStatement(ws->loc, tmp); ws->exp = new VarExp(ws->loc, tmp); Statement *ss = new ScopeStatement(ws->loc, new CompoundStatement(ws->loc, es, ws), ws->endloc); diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c index 1d5f3fc1064..24303835268 100644 --- a/gcc/d/dmd/traits.c +++ b/gcc/d/dmd/traits.c @@ -671,8 +671,8 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc) e->error("argument %s has no protection", o->toChars()); return new ErrorExp(); } - if (s->_scope) - s->semantic(s->_scope); + if (s->semanticRun == PASSinit) + s->semantic(NULL); const char *protName = protectionToChars(s->prot().kind); // TODO: How about package(names) assert(protName); @@ -1240,7 +1240,7 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc) ClassDeclaration *cd = sds->isClassDeclaration(); if (cd && e->ident == Id::allMembers) { - if (cd->_scope) + if (cd->semanticRun < PASSsemanticdone) cd->semantic(NULL); // Bugzilla 13668: Try to resolve forward reference struct PushBaseMembers diff --git a/gcc/testsuite/gdc.test/compilable/imports/test16214b.d b/gcc/testsuite/gdc.test/compilable/imports/test16214b.d new file mode 100644 index 00000000000..e2036fceb9f --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/imports/test16214b.d @@ -0,0 +1,10 @@ +module test16214b; +import test16214a; + +struct Appender() { int[] arr; } +struct Tuple() { alias A = Appender!(); } + +class EventLoop +{ + auto f() { auto x = [Tuple!().init]; } +} diff --git a/gcc/testsuite/gdc.test/compilable/test16214a.d b/gcc/testsuite/gdc.test/compilable/test16214a.d new file mode 100644 index 00000000000..2ea64d90329 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test16214a.d @@ -0,0 +1,7 @@ +// EXTRA_SOURCES: imports/test16214b.d +// REQUIRED_ARGS: -Icompilable/imports + +module test16214a; +import test16214b; + +class LibasyncEventLoop : EventLoop {} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b15875.d b/gcc/testsuite/gdc.test/fail_compilation/b15875.d new file mode 100644 index 00000000000..daa79b74a19 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b15875.d @@ -0,0 +1,10 @@ +/* TEST_OUTPUT: +--- +fail_compilation/b15875.d(9): Error: circular reference to variable `a` +fail_compilation/b15875.d(10): Error: circular reference to `b15875.f` +--- +*/ +// https://issues.dlang.org/show_bug.cgi?id=15875 +// https://issues.dlang.org/show_bug.cgi?id=17290 +d o(int[a]a)(){} +f.T f(){} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b17285.d b/gcc/testsuite/gdc.test/fail_compilation/b17285.d new file mode 100644 index 00000000000..7b79cf0666f --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b17285.d @@ -0,0 +1,15 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/b17285.d(14): Error: type `ONE` has no value +fail_compilation/b17285.d(14): Error: type `TWO` has no value +fail_compilation/b17285.d(14): Error: cannot implicitly convert expression `ONE` of type `b17285.ONE` to `int` +--- +*/ + +class ONE {} +enum TWO; + +void foo() { + foreach(key; [ONE, TWO, 1]) {} +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b19691.d b/gcc/testsuite/gdc.test/fail_compilation/b19691.d new file mode 100644 index 00000000000..8663512fd2a --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b19691.d @@ -0,0 +1,20 @@ +// REQUIRED_ARGS: -de +/* TEST_OUTPUT: +--- +fail_compilation/b19691.d(13): Error: forward reference to template `this` +fail_compilation/b19691.d(19): Deprecation: constructor `b19691.S2.this` all parameters have default arguments, but structs cannot have default constructors. +--- +*/ +// https://issues.dlang.org/show_bug.cgi?id=19691 +module b19691; + +struct S1 { + this(T...)(T) { + S2(""); + } +} + +struct S2 { + this(string) {} + this(S1 s = null) {} +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b19691e.d b/gcc/testsuite/gdc.test/fail_compilation/b19691e.d new file mode 100644 index 00000000000..21d0e908025 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b19691e.d @@ -0,0 +1,24 @@ +// REQUIRED_ARGS: -de +/* TEST_OUTPUT: +--- +fail_compilation/b19691e.d(17): Error: forward reference to template `this` +fail_compilation/b19691e.d(17): Error: constructor `b19691e.S2.this(S1 s = "")` is not callable using argument types `(string)` +fail_compilation/b19691e.d(17): Error: forward reference to template `this` +fail_compilation/b19691e.d(23): Deprecation: constructor `b19691e.S2.this` all parameters have default arguments, but structs cannot have default constructors. +--- +*/ +// https://issues.dlang.org/show_bug.cgi?id=19691 +module b19691e; + +struct S1 +{ + this(T)(T) + { + S2(""); + } +} + +struct S2 +{ + this(S1 s = ""){} +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b19717.d b/gcc/testsuite/gdc.test/fail_compilation/b19717.d new file mode 100644 index 00000000000..6a48b886e03 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b19717.d @@ -0,0 +1,16 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/b19717.d(16): Error: undefined identifier `Foo`, did you mean function `foo`? +fail_compilation/b19717.d(13): Error: forward reference to template `foo` +fail_compilation/b19717.d(13): Error: forward reference to inferred return type of function call `foo()` +--- +*/ + +enum bar = __traits(getMember, mixin(__MODULE__), "foo"); + +auto foo() { + return foo(); +} + +void foo(Foo) {} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b19717a.d b/gcc/testsuite/gdc.test/fail_compilation/b19717a.d new file mode 100644 index 00000000000..79a9de0ad7c --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b19717a.d @@ -0,0 +1,14 @@ +// REQUIRED_ARGS: -de +/* TEST_OUTPUT: +--- +fail_compilation/b19717a.d(14): Error: forward reference to template `a` +fail_compilation/b19717a.d(14): Error: forward reference to template `a` +fail_compilation/b19717a.d(14): Error: none of the overloads of `a` are callable using argument types `()`, candidates are: +fail_compilation/b19717a.d(13): `b19717a.a(int b)` +fail_compilation/b19717a.d(14): `b19717a.a(int b = a)` +--- +*/ +module b19717a; + +auto a(int b) {} +auto a(int b = a) {}