From e5d0ba591e28d8be1fb5775fb0418fee04af17d7 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Sun, 16 Jun 2019 07:50:07 +0000 Subject: [PATCH] d/dmd: Merge upstream dmd f8e38c001 Fixes bug where foreach(int) doesn't work on BigEndian targets by deprecating the use of index types smaller than a size_t/ptrdiff_t. Reviewed-on: https://github.com/dlang/dmd/pull/10009 From-SVN: r272350 --- gcc/d/dmd/MERGE | 2 +- gcc/d/dmd/statementsem.c | 44 +++++++++++-- gcc/testsuite/gdc.test/compilable/b16976.d | 66 +++++++++++++++++++ .../gdc.test/compilable/interpret3.d | 20 +++--- .../gdc.test/fail_compilation/diag16976.d | 44 +++++++++++++ .../gdc.test/fail_compilation/fail110.d | 2 +- libphobos/libdruntime/MERGE | 2 +- libphobos/libdruntime/rt/minfo.d | 8 +-- 8 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 gcc/testsuite/gdc.test/compilable/b16976.d create mode 100644 gcc/testsuite/gdc.test/fail_compilation/diag16976.d diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE index 03005e3b1ce..01c8cb0325d 100644 --- a/gcc/d/dmd/MERGE +++ b/gcc/d/dmd/MERGE @@ -1,4 +1,4 @@ -9746504883fc64f3dcec0cd4cacbb7a372d52158 +f8e38c001b9d7bd6586ee5b3dab7f7f199a69be7 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/statementsem.c b/gcc/d/dmd/statementsem.c index 0dc5e77b410..167836c0478 100644 --- a/gcc/d/dmd/statementsem.c +++ b/gcc/d/dmd/statementsem.c @@ -773,16 +773,48 @@ public: goto Lerror2; } + // Finish semantic on all foreach parameter types. + for (size_t i = 0; i < dim; i++) + { + Parameter *p = (*fs->parameters)[i]; + p->type = p->type->semantic(loc, sc2); + p->type = p->type->addStorageClass(p->storageClass); + } + + tn = tab->nextOf()->toBasetype(); + + if (dim == 2) + { + Type *tindex = (*fs->parameters)[0]->type; + if (!tindex->isintegral()) + { + fs->error("foreach: key cannot be of non-integral type `%s`", + tindex->toChars()); + goto Lerror2; + } + /* What cases to deprecate implicit conversions for: + * 1. foreach aggregate is a dynamic array + * 2. foreach body is lowered to _aApply (see special case below). + */ + Type *tv = (*fs->parameters)[1]->type->toBasetype(); + if ((tab->ty == Tarray || + (tn->ty != tv->ty && + (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) && + (tv->ty == Tchar || tv->ty == Twchar || tv->ty == Tdchar))) && + !Type::tsize_t->implicitConvTo(tindex)) + { + fs->deprecation("foreach: loop index implicitly converted from `size_t` to `%s`", + tindex->toChars()); + } + } + /* Look for special case of parsing char types out of char type * array. */ - tn = tab->nextOf()->toBasetype(); if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) { int i = (dim == 1) ? 0 : 1; // index of value Parameter *p = (*fs->parameters)[i]; - p->type = p->type->semantic(loc, sc2); - p->type = p->type->addStorageClass(p->storageClass); tnv = p->type->toBasetype(); if (tnv->ty != tn->ty && (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar)) @@ -809,8 +841,6 @@ public: { // Declare parameterss Parameter *p = (*fs->parameters)[i]; - p->type = p->type->semantic(loc, sc2); - p->type = p->type->addStorageClass(p->storageClass); VarDeclaration *var; if (dim == 2 && i == 0) @@ -908,6 +938,10 @@ public: fs->key = new VarDeclaration(loc, Type::tsize_t, idkey, NULL); fs->key->storage_class |= STCtemp; } + else if (fs->key->type->ty != Tsize_t) + { + tmp_length = new CastExp(loc, tmp_length, fs->key->type); + } if (fs->op == TOKforeach_reverse) fs->key->_init = new ExpInitializer(loc, tmp_length); else diff --git a/gcc/testsuite/gdc.test/compilable/b16976.d b/gcc/testsuite/gdc.test/compilable/b16976.d new file mode 100644 index 00000000000..f5f45ef9076 --- /dev/null +++ b/gcc/testsuite/gdc.test/compilable/b16976.d @@ -0,0 +1,66 @@ +/* REQUIRED_ARGS: -m64 +TEST_OUTPUT: +--- +compilable/b16976.d(33): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(34): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(35): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(36): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(41): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(42): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(43): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(44): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(50): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(51): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(52): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(53): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(58): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(59): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(60): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(61): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(62): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(63): Deprecation: foreach: loop index implicitly converted from `size_t` to `int` +compilable/b16976.d(64): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +compilable/b16976.d(65): Deprecation: foreach: loop index implicitly converted from `size_t` to `char` +--- +*/ +void main() +{ + int[] dyn = [1,2,3,4,5]; + int[5] sta = [1,2,3,4,5]; + char[] str = ['1','2','3','4','5']; + char[5] chr = ['1','2','3','4','5']; + + foreach(int i, v; dyn) { } + foreach_reverse(int i, v; dyn) { } + foreach(char i, v; dyn) { } + foreach_reverse(char i, v; dyn) { } + foreach(int i, v; sta) { } + foreach_reverse(int i, v; sta) { } + foreach(char i, v; sta) { } + foreach_reverse(char i, v; sta) { } + foreach(int i, v; str) { } + foreach_reverse(int i, v; str) { } + foreach(char i, v; str) { } + foreach_reverse(char i, v; str) { } + foreach(int i, v; chr) { } + foreach_reverse(int i, v; chr) { } + foreach(char i, v; chr) { } + foreach_reverse(char i, v; chr) { } + + foreach(int i, dchar v; dyn) { } + foreach_reverse(int i, dchar v; dyn) { } + foreach(char i, dchar v; dyn) { } + foreach_reverse(char i, dchar v; dyn) { } + foreach(int i, dchar v; sta) { } + foreach_reverse(int i, dchar v; sta) { } + foreach(char i, dchar v; sta) { } + foreach_reverse(char i, dchar v; sta) { } + foreach(int i, dchar v; str) { } + foreach_reverse(int i, dchar v; str) { } + foreach(char i, dchar v; str) { } + foreach_reverse(char i, dchar v; str) { } + foreach(int i, dchar v; chr) { } + foreach_reverse(int i, dchar v; chr) { } + foreach(char i, dchar v; chr) { } + foreach_reverse(char i, dchar v; chr) { } +} diff --git a/gcc/testsuite/gdc.test/compilable/interpret3.d b/gcc/testsuite/gdc.test/compilable/interpret3.d index 386743e6ddc..36cdd13148b 100644 --- a/gcc/testsuite/gdc.test/compilable/interpret3.d +++ b/gcc/testsuite/gdc.test/compilable/interpret3.d @@ -3396,13 +3396,13 @@ bool test3512() assert(q == 6); // _aApplycw2 - foreach (int i, wchar c; s) + foreach (ptrdiff_t i, wchar c; s) { assert(i >= 0 && i < s.length); } // _aApplycd2 - foreach (int i, dchar c; s) + foreach (ptrdiff_t i, dchar c; s) { assert(i >= 0 && i < s.length); } @@ -3424,13 +3424,13 @@ bool test3512() assert(q == 13); // _aApplywc2 - foreach (int i, char c; w) + foreach (ptrdiff_t i, char c; w) { assert(i >= 0 && i < w.length); } // _aApplywd2 - foreach (int i, dchar c; w) + foreach (ptrdiff_t i, dchar c; w) { assert(i >= 0 && i < w.length); } @@ -3454,19 +3454,19 @@ bool test3512() assert(q == 3); // _aApplydc2 - foreach (int i, char c; d) + foreach (ptrdiff_t i, char c; d) { assert(i >= 0 && i < d.length); } // _aApplydw2 - foreach (int i, wchar c; d) + foreach (ptrdiff_t i, wchar c; d) { assert(i >= 0 && i < d.length); } dchar[] dr = "squop"d.dup; - foreach (int n, char c; dr) + foreach (ptrdiff_t n, char c; dr) { if (n == 2) break; @@ -3482,7 +3482,7 @@ bool test3512() {} // _aApplyRdc2 - foreach_reverse (int n, char c; dr) + foreach_reverse (ptrdiff_t n, char c; dr) { if (n == 4) break; @@ -3490,14 +3490,14 @@ bool test3512() } // _aApplyRdw2 - foreach_reverse (int i, wchar c; dr) + foreach_reverse (ptrdiff_t i, wchar c; dr) { assert(i >= 0 && i < dr.length); } q = 0; wstring w2 = ['x', 'ü', 'm']; // foreach over array literals - foreach_reverse (int n, char c; w2) + foreach_reverse (ptrdiff_t n, char c; w2) { ++q; if (c == 'm') assert(n == 2 && q == 1); diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag16976.d b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d new file mode 100644 index 00000000000..ebfb72b493c --- /dev/null +++ b/gcc/testsuite/gdc.test/fail_compilation/diag16976.d @@ -0,0 +1,44 @@ +/* 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` +--- +*/ + +void main() +{ + int[] dyn = [1,2,3,4,5]; + int[5] sta = [1,2,3,4,5]; + char[] str = ['1','2','3','4','5']; + char[5] chr = ['1','2','3','4','5']; + foreach(float f, i; dyn) {} + foreach(float f, i; sta) {} + foreach(float f, i; str) {} + foreach(float f, i; chr) {} + foreach(float f, dchar i; dyn) {} + foreach(float f, dchar i; sta) {} + foreach(float f, dchar i; str) {} + foreach(float f, dchar i; chr) {} + foreach_reverse(float f, i; dyn) {} + foreach_reverse(float f, i; sta) {} + foreach_reverse(float f, i; str) {} + foreach_reverse(float f, i; chr) {} + foreach_reverse(float f, dchar i; dyn) {} + foreach_reverse(float f, dchar i; sta) {} + foreach_reverse(float f, dchar i; str) {} + foreach_reverse(float f, dchar i; chr) {} +} diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail110.d b/gcc/testsuite/gdc.test/fail_compilation/fail110.d index 3e9beb02121..47034019ea8 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail110.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail110.d @@ -14,6 +14,6 @@ void main() int i; int[] a; foreach (i; a) {} - foreach (int i, n; a) {} + foreach (size_t i, n; a) {} for (int i;;) {} } diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE index dec75f7cb33..a142195c62f 100644 --- a/libphobos/libdruntime/MERGE +++ b/libphobos/libdruntime/MERGE @@ -1,4 +1,4 @@ -aab44549221cb29434fe2feccaf1174af54dd79d +cb1583b4b7313bb6d79a5102b6c91e71f5181b19 The first line of this file holds the git revision number of the last merge done from the dlang/druntime repository. diff --git a/libphobos/libdruntime/rt/minfo.d b/libphobos/libdruntime/rt/minfo.d index 548bcc71c60..47228663562 100644 --- a/libphobos/libdruntime/rt/minfo.d +++ b/libphobos/libdruntime/rt/minfo.d @@ -125,7 +125,7 @@ struct ModuleGroup break; distloop: // search for next (previous) module in cycle. - foreach (int m, d; distance) + foreach (m, d; distance) { if (d == curdist) { @@ -470,7 +470,7 @@ struct ModuleGroup // pre-allocate enough space to hold all modules. ctors = (cast(immutable(ModuleInfo)**).malloc(len * (void*).sizeof)); ctoridx = 0; - foreach (int idx, m; _modules) + foreach (idx, m; _modules) { if (m.flags & relevantFlags) { @@ -582,8 +582,8 @@ struct ModuleGroup } // initialize the initial edges - foreach (int i, ref v; initialEdges) - v = i; + foreach (i, ref v; initialEdges) + v = cast(int)i; bool sort(ref immutable(ModuleInfo)*[] ctors, uint mask) { -- 2.30.2