d/dmd: Merge upstream dmd f8e38c001
authorIain Buclaw <ibuclaw@gcc.gnu.org>
Sun, 16 Jun 2019 07:50:07 +0000 (07:50 +0000)
committerIain Buclaw <ibuclaw@gcc.gnu.org>
Sun, 16 Jun 2019 07:50:07 +0000 (07:50 +0000)
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
gcc/d/dmd/statementsem.c
gcc/testsuite/gdc.test/compilable/b16976.d [new file with mode: 0644]
gcc/testsuite/gdc.test/compilable/interpret3.d
gcc/testsuite/gdc.test/fail_compilation/diag16976.d [new file with mode: 0644]
gcc/testsuite/gdc.test/fail_compilation/fail110.d
libphobos/libdruntime/MERGE
libphobos/libdruntime/rt/minfo.d

index 03005e3..01c8cb0 100644 (file)
@@ -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.
index 0dc5e77..167836c 100644 (file)
@@ -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 (file)
index 0000000..f5f45ef
--- /dev/null
@@ -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) { }
+}
index 386743e..36cdd13 100644 (file)
@@ -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 (file)
index 0000000..ebfb72b
--- /dev/null
@@ -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) {}
+}
index 3e9beb0..4703401 100644 (file)
@@ -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;;) {}
 }
index dec75f7..a142195 100644 (file)
@@ -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.
index 548bcc7..4722866 100644 (file)
@@ -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)
         {