From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1873) id 3A503397F428; Fri, 11 Jun 2021 18:16:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 3A503397F428 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset="utf-8" From: Iain Buclaw To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-1396] d: foreach over a tuple doesn't work on 16-bit targets (PR100999) X-Act-Checkin: gcc X-Git-Author: Iain Buclaw X-Git-Refname: refs/heads/master X-Git-Oldrev: b13f297f01c943aa167f7c6eb94bed40dce0d553 X-Git-Newrev: 68f46862d33707450bdf70cfddd91ae2a12527a8 Message-Id: <20210611181642.3A503397F428@sourceware.org> Date: Fri, 11 Jun 2021 18:16:42 +0000 (GMT) X-BeenThere: gcc-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Jun 2021 18:16:42 -0000 https://gcc.gnu.org/g:68f46862d33707450bdf70cfddd91ae2a12527a8 commit r12-1396-g68f46862d33707450bdf70cfddd91ae2a12527a8 Author: Iain Buclaw Date: Fri Jun 11 19:33:07 2021 +0200 d: foreach over a tuple doesn't work on 16-bit targets (PR100999) Improves semantic passes in the front-end around the `foreach' and `static foreach' statements to be more resilient to compiling in a minimal D runtime environment. Checking of the index type has been improved as well so now there won't be needless compiler errors when using 8 or 16-bit integers as index types when the size fits the expected loop range. gcc/d/ChangeLog: PR d/100999 * dmd/MERGE: Merge upstream dmd 7a3808254. libphobos/ChangeLog: PR d/100999 * src/MERGE: Merge upstream phobos 55bb17543. Diff: --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/cond.c | 29 +++++---- gcc/d/dmd/dinterpret.c | 9 +++ gcc/d/dmd/expression.c | 2 +- gcc/d/dmd/expressionsem.c | 12 ++-- gcc/d/dmd/statementsem.c | 36 +++++------ .../compilable/extra-files/minimal/object.d | 1 + gcc/testsuite/gdc.test/compilable/interpret5.d | 30 ++++++++++ gcc/testsuite/gdc.test/compilable/minimal3.d | 36 +++++++++++ gcc/testsuite/gdc.test/compilable/staticforeach.d | 38 ++++++++++++ gcc/testsuite/gdc.test/compilable/test21742.d | 13 ++++ gcc/testsuite/gdc.test/compilable/test22006.d | 14 +++++ gcc/testsuite/gdc.test/fail_compilation/b12504.d | 64 ++++++++++++++++++++ .../gdc.test/fail_compilation/diag16976.d | 69 +++++++++++++++++----- gcc/testsuite/gdc.test/fail_compilation/fail117.d | 6 +- .../gdc.test/fail_compilation/fail22006.d | 22 +++++++ .../gdc.test/fail_compilation/fail238_m32.d | 8 +-- .../gdc.test/fail_compilation/fail238_m64.d | 8 +-- .../gdc.test/fail_compilation/fail7424b.d | 2 +- .../gdc.test/fail_compilation/fail7424c.d | 2 +- .../gdc.test/fail_compilation/fail7424d.d | 2 +- .../gdc.test/fail_compilation/fail7424e.d | 2 +- .../gdc.test/fail_compilation/fail7424f.d | 2 +- .../gdc.test/fail_compilation/fail7424g.d | 2 +- .../gdc.test/fail_compilation/fail7424h.d | 2 +- .../gdc.test/fail_compilation/fail7424i.d | 2 +- gcc/testsuite/gdc.test/fail_compilation/fail9766.d | 4 +- gcc/testsuite/gdc.test/fail_compilation/ice9406.d | 3 +- .../gdc.test/fail_compilation/test21927.d | 20 +++++++ .../gdc.test/fail_compilation/test21939.d | 9 +++ libphobos/src/MERGE | 2 +- libphobos/src/std/typecons.d | 15 ++--- 32 files changed, 388 insertions(+), 80 deletions(-) diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index a617f285eac..d20785d9126 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -4a4e46a6f304a667e0c05d4455706ec2056ffddc +7a3808254878df8cb70a055bea58afc79187b778 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/cond.c b/gcc/d/dmd/cond.c index 6f112ad909c..6c7dc9eb1a3 100644 --- a/gcc/d/dmd/cond.c +++ b/gcc/d/dmd/cond.c @@ -112,6 +112,7 @@ static void lowerArrayAggregate(StaticForeach *sfe, Scope *sc) sfe->aggrfe->aggr = new TupleExp(aggr->loc, es); sfe->aggrfe->aggr = expressionSemantic(sfe->aggrfe->aggr, sc); sfe->aggrfe->aggr = sfe->aggrfe->aggr->optimize(WANTvalue); + sfe->aggrfe->aggr = sfe->aggrfe->aggr->ctfeInterpret(); } else { @@ -198,7 +199,8 @@ static TypeStruct *createTupleType(Loc loc, Expressions *e) Type *ty = new TypeTypeof(loc, new TupleExp(loc, e)); sdecl->members->push(new VarDeclaration(loc, ty, fid, NULL)); TypeStruct *r = (TypeStruct *)sdecl->type; - r->vtinfo = TypeInfoStructDeclaration::create(r); // prevent typeinfo from going to object file + if (global.params.useTypeInfo && Type::dtypeinfo) + r->vtinfo = TypeInfoStructDeclaration::create(r); // prevent typeinfo from going to object file return r; } @@ -312,15 +314,25 @@ static void lowerNonArrayAggregate(StaticForeach *sfe, Scope *sc) Identifier *idres = Identifier::generateId("__res"); VarDeclaration *vard = new VarDeclaration(aloc, aty, idres, NULL); Statements *s2 = new Statements(); - s2->push(new ExpStatement(aloc, vard)); - Expression *catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]); - s2->push(createForeach(sfe, aloc, pparams[1], new ExpStatement(aloc, catass))); - s2->push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres))); + + // Run 'typeof' gagged to avoid duplicate errors and if it fails just create + // an empty foreach to expose them. + unsigned olderrors = global.startGagging(); + ety = typeSemantic(ety, aloc, sc); + if (global.endGagging(olderrors)) + s2->push(createForeach(sfe, aloc, pparams[1], NULL)); + else + { + s2->push(new ExpStatement(aloc, vard)); + Expression *catass = new CatAssignExp(aloc, new IdentifierExp(aloc, idres), res[1]); + s2->push(createForeach(sfe, aloc, pparams[1], new ExpStatement(aloc, catass))); + s2->push(new ReturnStatement(aloc, new IdentifierExp(aloc, idres))); + } Expression *aggr; Type *indexty; - if (sfe->rangefe && (indexty = typeSemantic(ety, aloc, sc))->isintegral()) + if (sfe->rangefe && (indexty = ety)->isintegral()) { sfe->rangefe->lwr->type = indexty; sfe->rangefe->upr->type = indexty; @@ -384,11 +396,6 @@ void staticForeachPrepare(StaticForeach *sfe, Scope *sc) sfe->aggrfe->aggr = expressionSemantic(sfe->aggrfe->aggr, sc); sc = sc->endCTFE(); sfe->aggrfe->aggr = sfe->aggrfe->aggr->optimize(WANTvalue); - Type *tab = sfe->aggrfe->aggr->type->toBasetype(); - if (tab->ty != Ttuple) - { - sfe->aggrfe->aggr = sfe->aggrfe->aggr->ctfeInterpret(); - } } if (sfe->aggrfe && sfe->aggrfe->aggr->type->toBasetype()->ty == Terror) diff --git a/gcc/d/dmd/dinterpret.c b/gcc/d/dmd/dinterpret.c index 5e71f3b24a1..ab9d88c660c 100644 --- a/gcc/d/dmd/dinterpret.c +++ b/gcc/d/dmd/dinterpret.c @@ -643,7 +643,16 @@ Expression *ctfeInterpret(Expression *e) case TOKfloat64: case TOKcomplex80: case TOKnull: + case TOKvoid: case TOKstring: + case TOKthis: + case TOKsuper: + case TOKtype: + case TOKtypeid: + case TOKtemplate: // non-eponymous template/instance + case TOKscope: // ditto + case TOKdottd: // ditto, e.e1 doesn't matter here + case TOKdot: // ditto if (e->type->ty == Terror) return new ErrorExp(); /* fall through */ diff --git a/gcc/d/dmd/expression.c b/gcc/d/dmd/expression.c index 88f13e9669b..153819aa172 100644 --- a/gcc/d/dmd/expression.c +++ b/gcc/d/dmd/expression.c @@ -1044,7 +1044,7 @@ bool Expression::checkPostblit(Scope *sc, Type *t) t = t->baseElemOf(); if (t->ty == Tstruct) { - if (global.params.useTypeInfo) + if (global.params.useTypeInfo && Type::dtypeinfo) { // Bugzilla 11395: Require TypeInfo generation for array concatenation semanticTypeInfo(sc, t); diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c index 4a37d0fcba2..5ae5fe6a717 100644 --- a/gcc/d/dmd/expressionsem.c +++ b/gcc/d/dmd/expressionsem.c @@ -1082,11 +1082,6 @@ static Expression *resolvePropertiesX(Scope *sc, Expression *e1, Expression *e2 if (checkUnsafeAccess(sc, e1, true, true)) return new ErrorExp(); } - else if (e1->op == TOKdot) - { - e1->error("expression has no value"); - return new ErrorExp(); - } else if (e1->op == TOKcall) { CallExp *ce = (CallExp *)e1; @@ -4513,11 +4508,18 @@ public: void visit(DotTemplateExp *e) { + if (e->type) + { + result = e; + return; + } if (Expression *ex = unaSemantic(e, sc)) { result = ex; return; } + // 'void' like TemplateExp + e->type = Type::tvoid; result = e; } diff --git a/gcc/d/dmd/statementsem.c b/gcc/d/dmd/statementsem.c index 491d9c9bce9..24e534e50a8 100644 --- a/gcc/d/dmd/statementsem.c +++ b/gcc/d/dmd/statementsem.c @@ -563,9 +563,6 @@ public: else { e = resolveProperties(sc, e); - type = e->type; - if (paramtype) - type = paramtype; Initializer *ie = new ExpInitializer(Loc(), e); VarDeclaration *v = new VarDeclaration(loc, type, ident, ie); if (storageClass & STCref) @@ -646,22 +643,23 @@ public: } } p->type = typeSemantic(p->type, loc, sc); - TY keyty = p->type->ty; - if (keyty != Tint32 && keyty != Tuns32) + + if (!p->type->isintegral()) { - if (global.params.isLP64) - { - if (keyty != Tint64 && keyty != Tuns64) - { - fs->error("foreach: key type must be int or uint, long or ulong, not %s", p->type->toChars()); - return false; - } - } - else - { - fs->error("foreach: key type must be int or uint, not %s", p->type->toChars()); - return false; - } + fs->error("foreach: key cannot be of non-integral type `%s`", + p->type->toChars()); + return false; + } + + unsigned length = te ? te->exps->length : tuple->arguments->length; + IntRange dimrange = IntRange(SignExtendedNumber(length)).cast(Type::tsize_t); + // https://issues.dlang.org/show_bug.cgi?id=12504 + dimrange.imax = SignExtendedNumber(dimrange.imax.value-1); + if (!IntRange::fromType(p->type).contains(dimrange)) + { + fs->error("index type `%s` cannot cover index range 0..%llu", + p->type->toChars(), (ulonglong)length); + return false; } Initializer *ie = new ExpInitializer(Loc(), new IntegerExp(k)); VarDeclaration *var = new VarDeclaration(loc, p->type, p->ident, ie); @@ -1073,6 +1071,8 @@ public: { TypeSArray *ta = (TypeSArray *)tab; IntRange dimrange = getIntRange(ta->dim); + // https://issues.dlang.org/show_bug.cgi?id=12504 + dimrange.imax = SignExtendedNumber(dimrange.imax.value-1); if (!IntRange::fromType(var->type).contains(dimrange)) { fs->error("index type `%s` cannot cover index range 0..%llu", p->type->toChars(), ta->dim->toInteger()); diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/minimal/object.d b/gcc/testsuite/gdc.test/compilable/extra-files/minimal/object.d new file mode 100644 index 00000000000..c7060b0d96c --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/extra-files/minimal/object.d @@ -0,0 +1 @@ +module object; diff --git a/gcc/testsuite/gdc.test/compilable/interpret5.d b/gcc/testsuite/gdc.test/compilable/interpret5.d new file mode 100644 index 00000000000..ce13a5ab182 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/interpret5.d @@ -0,0 +1,30 @@ +// https://issues.dlang.org/show_bug.cgi?id=21927 +/* +TEST_OUTPUT: +--- +T1(Args...) +T1!() +T2(Args2...) +T2!() +this.T2(Args2...) +this.T2!() +--- +*/ +template T1(Args...) {} + +pragma(msg, T1); // TOK.template_ +pragma(msg, T1!()); // TOK.scope_ + +struct S +{ + template T2(Args2...) {} + + pragma(msg, S.T2); // TOK.template_ + pragma(msg, S.T2!()); // TOK.scope_ + + void fun() + { + pragma(msg, this.T2); // TOK.dotTemplateDeclaration + pragma(msg, this.T2!()); // TOK.dot + } +} diff --git a/gcc/testsuite/gdc.test/compilable/minimal3.d b/gcc/testsuite/gdc.test/compilable/minimal3.d new file mode 100644 index 00000000000..e8106b62003 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/minimal3.d @@ -0,0 +1,36 @@ +// DFLAGS: +// REQUIRED_ARGS: -defaultlib= +// EXTRA_SOURCES: extra-files/minimal/object.d + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=19234 +void issue19234() +{ + static struct A {} + A[10] a; + A[10] b; + b[] = a[]; +} + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=22005 +void issue22005() +{ + enum int[4] foo = [1,2,3,4]; + static foreach (i, e; foo) + { + } +} + +/**********************************************/ +// https://issues.dlang.org/show_bug.cgi?id=22006 +void issue22006() +{ + alias size_t = typeof(int.sizeof); + alias AliasSeq(T...) = T; + + foreach (size_t i, e; [0, 1, 2, 3]) { } + static foreach (size_t i, e; [0, 1, 2, 3]) { } + foreach (size_t i, e; AliasSeq!(0, 1, 2, 3)) { } + static foreach (size_t i, e; AliasSeq!(0, 1, 2, 3)) { } +} diff --git a/gcc/testsuite/gdc.test/compilable/staticforeach.d b/gcc/testsuite/gdc.test/compilable/staticforeach.d index 48d06b418d3..8a54f32de57 100644 --- a/gcc/testsuite/gdc.test/compilable/staticforeach.d +++ b/gcc/testsuite/gdc.test/compilable/staticforeach.d @@ -115,6 +115,8 @@ bug17688 T foo2 T2 +TestStaticForeach2 +issue22007 1 2 '3' 2 3 '4' 0 1 @@ -840,3 +842,39 @@ struct T2{ struct S{} } static assert(is(__traits(parent,T2.S)==T2)); + +struct TestStaticForeach2 +{ +static: + // StringExp + char[] test(string str)() + { + char[] s; + static foreach (c; str) + { + s ~= c; + } + return s; + } + static assert(test!"tёstñ" == ['t', '\xd1', '\x91', 's', 't', '\xc3', '\xb1']); + + static foreach (c; "") + { + static assert(0); + } + + // NullExp + enum int[] a = null; + static foreach (c; a) + { + static assert(0); + } +} + +//https://issues.dlang.org/show_bug.cgi?id=22007 +void issue22007() +{ + immutable int[32] array = 1; + foreach (size_t a, int b; array) {} + static foreach (size_t a, int b; array) { } +} diff --git a/gcc/testsuite/gdc.test/compilable/test21742.d b/gcc/testsuite/gdc.test/compilable/test21742.d new file mode 100644 index 00000000000..b8f5df4b46d --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test21742.d @@ -0,0 +1,13 @@ +// https://issues.dlang.org/show_bug.cgi?id=21742 + +int foo()() { return 0; } + +struct B +{ + int foo()() { return 0; } +} + +static assert(is(typeof(foo) == void)); + +// failed, gagged error: expression B().foo()() has no type +static assert(is(typeof(B().foo) == void)); diff --git a/gcc/testsuite/gdc.test/compilable/test22006.d b/gcc/testsuite/gdc.test/compilable/test22006.d new file mode 100644 index 00000000000..913dd859012 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/test22006.d @@ -0,0 +1,14 @@ +// https://issues.dlang.org/show_bug.cgi?id=22006 +void test22006() +{ + alias AliasSeq(TList...) = TList; + { + alias aseq = AliasSeq!(0, 1, 2, 3); + static foreach (ubyte i; 0 .. aseq.length) {} + static foreach (ubyte i, x; aseq) {} + } + { + static foreach (ubyte i; 0 .. [0, 1, 2, 3].length) {} + static foreach (ubyte i, x; [0, 1, 2, 3]) {} + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/b12504.d b/gcc/testsuite/gdc.test/fail_compilation/b12504.d new file mode 100644 index 00000000000..0bb104eded7 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/b12504.d @@ -0,0 +1,64 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/b12504.d(26): Error: cannot implicitly convert expression `257$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ubyte` +fail_compilation/b12504.d(27): Error: index type `ubyte` cannot cover index range 0..257 +fail_compilation/b12504.d(31): Error: cannot implicitly convert expression `129$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `byte` +fail_compilation/b12504.d(32): Error: index type `byte` cannot cover index range 0..129 +fail_compilation/b12504.d(36): Error: cannot implicitly convert expression `65537$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ushort` +fail_compilation/b12504.d(37): Error: index type `ushort` cannot cover index range 0..65537 +fail_compilation/b12504.d(41): Error: cannot implicitly convert expression `32769$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `short` +fail_compilation/b12504.d(42): Error: index type `short` cannot cover index range 0..32769 +fail_compilation/b12504.d(46): Error: cannot implicitly convert expression `257$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ubyte` +fail_compilation/b12504.d(47): Error: index type `ubyte` cannot cover index range 0..257 +fail_compilation/b12504.d(51): Error: cannot implicitly convert expression `129$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `byte` +fail_compilation/b12504.d(52): Error: index type `byte` cannot cover index range 0..129 +fail_compilation/b12504.d(56): Error: cannot implicitly convert expression `65537$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `ushort` +fail_compilation/b12504.d(57): Error: index type `ushort` cannot cover index range 0..65537 +fail_compilation/b12504.d(61): Error: cannot implicitly convert expression `32769$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `short` +fail_compilation/b12504.d(62): Error: index type `short` cannot cover index range 0..32769 +--- +*/ +void main() +{ + { + int[0xFF + 2] sta; + foreach (ubyte i; 0 .. sta.length) {} + foreach (ubyte i, x; sta) {} + } + { + int[0x7F + 2] sta; + foreach (byte i; 0 .. sta.length) {} + foreach (byte i, x; sta) {} + } + { + int[0xFFFF + 2] sta; + foreach (ushort i; 0 .. sta.length) {} + foreach (ushort i, x; sta) {} + } + { + int[0x7FFF + 2] sta; + foreach (short i; 0 .. sta.length) {} + foreach (short i, x; sta) {} + } + { + immutable int[0xFF + 2] sta; + static foreach (ubyte i; 0 .. sta.length) {} + static foreach (ubyte i, x; sta) {} + } + { + immutable int[0x7F + 2] sta; + static foreach (byte i; 0 .. sta.length) {} + static foreach (byte i, x; sta) {} + } + { + immutable int[0xFFFF + 2] sta; + static foreach (ushort i; 0 .. sta.length) {} + static foreach (ushort i, x; sta) {} + } + { + immutable int[0x7FFF + 2] sta; + static foreach (short i; 0 .. sta.length) {} + static foreach (short i, x; sta) {} + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16976.d b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d index ebfb72b493c..1dbacfd3e54 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/diag16976.d +++ b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d @@ -1,21 +1,37 @@ /* TEST_OUTPUT: --- -fail_compilation/diag16976.d(28): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(29): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(30): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(31): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(32): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(33): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(34): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(35): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(36): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(37): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(38): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(39): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(40): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(41): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(42): Error: foreach: key cannot be of non-integral type `float` -fail_compilation/diag16976.d(43): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(44): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(45): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(46): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(47): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(48): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(49): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(50): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(51): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(52): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(53): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(54): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(55): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(56): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(57): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(58): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(59): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(65): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(66): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(67): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(68): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(69): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(70): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(71): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(72): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(73): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(74): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(75): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(76): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(77): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(78): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(79): Error: foreach: key cannot be of non-integral type `float` +fail_compilation/diag16976.d(80): Error: foreach: key cannot be of non-integral type `float` --- */ @@ -41,4 +57,25 @@ void main() foreach_reverse(float f, dchar i; sta) {} foreach_reverse(float f, dchar i; str) {} foreach_reverse(float f, dchar i; chr) {} + + immutable int[] idyn = [1,2,3,4,5]; + immutable int[5] ista = [1,2,3,4,5]; + immutable char[] istr = ['1','2','3','4','5']; + immutable char[5] ichr = ['1','2','3','4','5']; + static foreach(float f, i; idyn) {} + static foreach(float f, i; ista) {} + static foreach(float f, i; istr) {} + static foreach(float f, i; ichr) {} + static foreach(float f, dchar i; idyn) {} + static foreach(float f, dchar i; ista) {} + static foreach(float f, dchar i; istr) {} + static foreach(float f, dchar i; ichr) {} + static foreach_reverse(float f, i; idyn) {} + static foreach_reverse(float f, i; ista) {} + static foreach_reverse(float f, i; istr) {} + static foreach_reverse(float f, i; ichr) {} + static foreach_reverse(float f, dchar i; idyn) {} + static foreach_reverse(float f, dchar i; ista) {} + static foreach_reverse(float f, dchar i; istr) {} + static foreach_reverse(float f, dchar i; ichr) {} } diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail117.d b/gcc/testsuite/gdc.test/fail_compilation/fail117.d index f39a48db67c..9279d54276c 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail117.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail117.d @@ -1,8 +1,10 @@ /* TEST_OUTPUT: --- -fail_compilation/fail117.d(35): Error: expression has no value -fail_compilation/fail117.d(36): Error: expression has no value +fail_compilation/fail117.d(37): Error: expression `foo.mixin MGettor!(a) geta; +` is `void` and has no value +fail_compilation/fail117.d(38): Error: expression `foo.mixin MGettor!(b) getb; +` is `void` and has no value --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail22006.d b/gcc/testsuite/gdc.test/fail_compilation/fail22006.d new file mode 100644 index 00000000000..89bbc289414 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/fail22006.d @@ -0,0 +1,22 @@ +/* +TEST_OUTPUT: +--- +fail_compilation/fail22006.d(15): Error: cannot implicitly convert expression `4$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `bool` +fail_compilation/fail22006.d(16): Error: index type `bool` cannot cover index range 0..4 +fail_compilation/fail22006.d(19): Error: cannot implicitly convert expression `4$?:32=u|64=LU$` of type `$?:32=uint|64=ulong$` to `bool` +fail_compilation/fail22006.d(20): Error: index type `bool` cannot cover index range 0..4 +--- +*/ +void test22006() +{ + alias AliasSeq(TList...) = TList; + { + alias aseq = AliasSeq!(0, 1, 2, 3); + static foreach (bool i; 0 .. aseq.length) {} + static foreach (bool i, x; aseq) {} + } + { + static foreach (bool i; 0 .. [0, 1, 2, 3].length) {} + static foreach (bool i, x; [0, 1, 2, 3]) {} + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d b/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d index cb565ba2d39..a312dc07290 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail238_m32.d @@ -3,10 +3,10 @@ TEST_OUTPUT: --- fail_compilation/fail238_m32.d(21): Error: cannot implicitly convert expression `"a"` of type `string` to `uint` -fail_compilation/fail238_m32.d(24): Error: cannot interpret X!() at compile time -fail_compilation/fail238_m32.d(29): Error: template instance fail238_m32.A!"a" error instantiating -fail_compilation/fail238_m32.d(35): instantiated from here: M!(q) -fail_compilation/fail238_m32.d(35): while evaluating pragma(msg, M!(q)) +fail_compilation/fail238_m32.d(24): Error: cannot implicitly convert expression `X!()` of type `void` to `const(string)` +fail_compilation/fail238_m32.d(29): Error: template instance `fail238_m32.A!"a"` error instantiating +fail_compilation/fail238_m32.d(35): instantiated from here: `M!(q)` +fail_compilation/fail238_m32.d(35): while evaluating `pragma(msg, M!(q))` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d b/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d index 08837b2a554..dc7a50ea546 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail238_m64.d @@ -3,10 +3,10 @@ TEST_OUTPUT: --- fail_compilation/fail238_m64.d(21): Error: cannot implicitly convert expression `"a"` of type `string` to `ulong` -fail_compilation/fail238_m64.d(24): Error: cannot interpret X!() at compile time -fail_compilation/fail238_m64.d(29): Error: template instance fail238_m64.A!"a" error instantiating -fail_compilation/fail238_m64.d(35): instantiated from here: M!(q) -fail_compilation/fail238_m64.d(35): while evaluating pragma(msg, M!(q)) +fail_compilation/fail238_m64.d(24): Error: cannot implicitly convert expression `X!()` of type `void` to `const(string)` +fail_compilation/fail238_m64.d(29): Error: template instance `fail238_m64.A!"a"` error instantiating +fail_compilation/fail238_m64.d(35): instantiated from here: `M!(q)` +fail_compilation/fail238_m64.d(35): while evaluating `pragma(msg, M!(q))` --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d index 1a7e092fb5b..737958ca6a3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424b.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424b.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424b.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424b diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d index 1c0654091f7..e804d72100b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424c.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424c.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424c.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424c diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d index d784a7580c4..5ef9463aeb2 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424d.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424d.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424d.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424d diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d index 3bf3a2d97db..ddf4ded953a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424e.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424e.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424e.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424e diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d index 266163de75d..751b6259d31 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424f.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424f.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424f.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424f diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d index aca6586c8f8..d4fa4635d8d 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424g.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424g.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424g.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424g diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d index e08eac13de2..56184a5f5a1 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424h.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424h.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424h.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424g diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d index 1c2cb1cd687..37042f741f3 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail7424i.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail7424i.d(10): Error: cannot resolve type for this.g()() +fail_compilation/fail7424i.d(10): Error: expression `this.g()()` is `void` and has no value --- */ struct S7424g diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail9766.d b/gcc/testsuite/gdc.test/fail_compilation/fail9766.d index d75d1bc44e7..58cabe3825b 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail9766.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail9766.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/fail9766.d(14): Error: cannot interpret Foo!int at compile time +fail_compilation/fail9766.d(14): Error: integer constant expression expected instead of `Foo!int` +fail_compilation/fail9766.d(14): Error: alignment must be an integer positive power of 2, not Foo!int fail_compilation/fail9766.d(17): Error: alignment must be an integer positive power of 2, not -1 fail_compilation/fail9766.d(20): Error: alignment must be an integer positive power of 2, not 0 fail_compilation/fail9766.d(23): Error: alignment must be an integer positive power of 2, not 3 @@ -9,6 +10,7 @@ fail_compilation/fail9766.d(26): Error: alignment must be an integer positive po --- */ +#line 12 template Foo(T) {} align(Foo!int) diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice9406.d b/gcc/testsuite/gdc.test/fail_compilation/ice9406.d index d8c0837699a..c1807a0f542 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/ice9406.d +++ b/gcc/testsuite/gdc.test/fail_compilation/ice9406.d @@ -1,7 +1,8 @@ /* TEST_OUTPUT: --- -fail_compilation/ice9406.d(21): Error: expression has no value +fail_compilation/ice9406.d(22): Error: `s1.mixin Mixin!() t1; +` has no effect --- */ diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21927.d b/gcc/testsuite/gdc.test/fail_compilation/test21927.d new file mode 100644 index 00000000000..fa23285e8b0 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test21927.d @@ -0,0 +1,20 @@ +// https://issues.dlang.org/show_bug.cgi?id=21927 +/* +TEST_OUTPUT: +--- +fail_compilation/test21927.d(17): Error: invalid `foreach` aggregate `this.T2(Args2...)` +fail_compilation/test21927.d(18): Error: invalid `foreach` aggregate `this.T2!()` +--- +*/ + +struct S +{ + template T2(Args2...) {} + + void fun() + { + // original test case + static foreach (p; this.T2) {} // ICE + static foreach (p; this.T2!()) {} // ICE + } +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/test21939.d b/gcc/testsuite/gdc.test/fail_compilation/test21939.d new file mode 100644 index 00000000000..cb755ef2679 --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/test21939.d @@ -0,0 +1,9 @@ +// https://issues.dlang.org/show_bug.cgi?id=21939 +/* +TEST_OUTPUT: +--- +fail_compilation/test21939.d(9): Error: invalid `foreach` aggregate `Object`, define `opApply()`, range primitives, or use `.tupleof` +--- +*/ + +static foreach (a; Object) {} diff --git a/libphobos/src/MERGE b/libphobos/src/MERGE index ac709f9c807..01cf5943b03 100644 --- a/libphobos/src/MERGE +++ b/libphobos/src/MERGE @@ -1,4 +1,4 @@ -63f4caa900e17c541042617b2fa187059b86bf88 +55bb17543138a87c376a84745f2a30ec00bdecd9 The first line of this file holds the git revision number of the last merge done from the dlang/phobos repository. diff --git a/libphobos/src/std/typecons.d b/libphobos/src/std/typecons.d index 55119fc2780..84e876f3c59 100644 --- a/libphobos/src/std/typecons.d +++ b/libphobos/src/std/typecons.d @@ -5935,13 +5935,7 @@ mixin template Proxy(alias a) // built-in type field, manifest constant, and static non-mutable field enum opDispatch = mixin("a."~name); } - else static if (is(typeof(mixin("a."~name))) || __traits(getOverloads, a, name).length != 0) - { - // field or property function - @property auto ref opDispatch(this X)() { return mixin("a."~name); } - @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); } - } - else + else static if (__traits(isTemplate, mixin("a."~name))) { // member template template opDispatch(T...) @@ -5950,6 +5944,13 @@ mixin template Proxy(alias a) auto ref opDispatch(this X, Args...)(auto ref Args args){ return mixin("a."~name~targs~"(args)"); } } } + else + { + // field or property function + @property auto ref opDispatch(this X)() { return mixin("a."~name); } + @property auto ref opDispatch(this X, V)(auto ref V v) { return mixin("a."~name~" = v"); } + } + } import std.traits : isArray;