Commit e5d0ba59 by Iain Buclaw

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
parent 9bf706aa
9746504883fc64f3dcec0cd4cacbb7a372d52158 f8e38c001b9d7bd6586ee5b3dab7f7f199a69be7
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository. merge done from the dlang/dmd repository.
...@@ -773,16 +773,48 @@ public: ...@@ -773,16 +773,48 @@ public:
goto Lerror2; 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 /* Look for special case of parsing char types out of char type
* array. * array.
*/ */
tn = tab->nextOf()->toBasetype();
if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar) if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
{ {
int i = (dim == 1) ? 0 : 1; // index of value int i = (dim == 1) ? 0 : 1; // index of value
Parameter *p = (*fs->parameters)[i]; Parameter *p = (*fs->parameters)[i];
p->type = p->type->semantic(loc, sc2);
p->type = p->type->addStorageClass(p->storageClass);
tnv = p->type->toBasetype(); tnv = p->type->toBasetype();
if (tnv->ty != tn->ty && if (tnv->ty != tn->ty &&
(tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar)) (tnv->ty == Tchar || tnv->ty == Twchar || tnv->ty == Tdchar))
...@@ -809,8 +841,6 @@ public: ...@@ -809,8 +841,6 @@ public:
{ {
// Declare parameterss // Declare parameterss
Parameter *p = (*fs->parameters)[i]; Parameter *p = (*fs->parameters)[i];
p->type = p->type->semantic(loc, sc2);
p->type = p->type->addStorageClass(p->storageClass);
VarDeclaration *var; VarDeclaration *var;
if (dim == 2 && i == 0) if (dim == 2 && i == 0)
...@@ -908,6 +938,10 @@ public: ...@@ -908,6 +938,10 @@ public:
fs->key = new VarDeclaration(loc, Type::tsize_t, idkey, NULL); fs->key = new VarDeclaration(loc, Type::tsize_t, idkey, NULL);
fs->key->storage_class |= STCtemp; 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) if (fs->op == TOKforeach_reverse)
fs->key->_init = new ExpInitializer(loc, tmp_length); fs->key->_init = new ExpInitializer(loc, tmp_length);
else else
......
/* 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) { }
}
...@@ -3396,13 +3396,13 @@ bool test3512() ...@@ -3396,13 +3396,13 @@ bool test3512()
assert(q == 6); assert(q == 6);
// _aApplycw2 // _aApplycw2
foreach (int i, wchar c; s) foreach (ptrdiff_t i, wchar c; s)
{ {
assert(i >= 0 && i < s.length); assert(i >= 0 && i < s.length);
} }
// _aApplycd2 // _aApplycd2
foreach (int i, dchar c; s) foreach (ptrdiff_t i, dchar c; s)
{ {
assert(i >= 0 && i < s.length); assert(i >= 0 && i < s.length);
} }
...@@ -3424,13 +3424,13 @@ bool test3512() ...@@ -3424,13 +3424,13 @@ bool test3512()
assert(q == 13); assert(q == 13);
// _aApplywc2 // _aApplywc2
foreach (int i, char c; w) foreach (ptrdiff_t i, char c; w)
{ {
assert(i >= 0 && i < w.length); assert(i >= 0 && i < w.length);
} }
// _aApplywd2 // _aApplywd2
foreach (int i, dchar c; w) foreach (ptrdiff_t i, dchar c; w)
{ {
assert(i >= 0 && i < w.length); assert(i >= 0 && i < w.length);
} }
...@@ -3454,19 +3454,19 @@ bool test3512() ...@@ -3454,19 +3454,19 @@ bool test3512()
assert(q == 3); assert(q == 3);
// _aApplydc2 // _aApplydc2
foreach (int i, char c; d) foreach (ptrdiff_t i, char c; d)
{ {
assert(i >= 0 && i < d.length); assert(i >= 0 && i < d.length);
} }
// _aApplydw2 // _aApplydw2
foreach (int i, wchar c; d) foreach (ptrdiff_t i, wchar c; d)
{ {
assert(i >= 0 && i < d.length); assert(i >= 0 && i < d.length);
} }
dchar[] dr = "squop"d.dup; dchar[] dr = "squop"d.dup;
foreach (int n, char c; dr) foreach (ptrdiff_t n, char c; dr)
{ {
if (n == 2) if (n == 2)
break; break;
...@@ -3482,7 +3482,7 @@ bool test3512() ...@@ -3482,7 +3482,7 @@ bool test3512()
{} {}
// _aApplyRdc2 // _aApplyRdc2
foreach_reverse (int n, char c; dr) foreach_reverse (ptrdiff_t n, char c; dr)
{ {
if (n == 4) if (n == 4)
break; break;
...@@ -3490,14 +3490,14 @@ bool test3512() ...@@ -3490,14 +3490,14 @@ bool test3512()
} }
// _aApplyRdw2 // _aApplyRdw2
foreach_reverse (int i, wchar c; dr) foreach_reverse (ptrdiff_t i, wchar c; dr)
{ {
assert(i >= 0 && i < dr.length); assert(i >= 0 && i < dr.length);
} }
q = 0; q = 0;
wstring w2 = ['x', 'ü', 'm']; // foreach over array literals wstring w2 = ['x', 'ü', 'm']; // foreach over array literals
foreach_reverse (int n, char c; w2) foreach_reverse (ptrdiff_t n, char c; w2)
{ {
++q; ++q;
if (c == 'm') assert(n == 2 && q == 1); if (c == 'm') assert(n == 2 && q == 1);
......
/* 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) {}
}
...@@ -14,6 +14,6 @@ void main() ...@@ -14,6 +14,6 @@ void main()
int i; int i;
int[] a; int[] a;
foreach (i; a) {} foreach (i; a) {}
foreach (int i, n; a) {} foreach (size_t i, n; a) {}
for (int i;;) {} for (int i;;) {}
} }
aab44549221cb29434fe2feccaf1174af54dd79d cb1583b4b7313bb6d79a5102b6c91e71f5181b19
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the dlang/druntime repository. merge done from the dlang/druntime repository.
...@@ -125,7 +125,7 @@ struct ModuleGroup ...@@ -125,7 +125,7 @@ struct ModuleGroup
break; break;
distloop: distloop:
// search for next (previous) module in cycle. // search for next (previous) module in cycle.
foreach (int m, d; distance) foreach (m, d; distance)
{ {
if (d == curdist) if (d == curdist)
{ {
...@@ -470,7 +470,7 @@ struct ModuleGroup ...@@ -470,7 +470,7 @@ struct ModuleGroup
// pre-allocate enough space to hold all modules. // pre-allocate enough space to hold all modules.
ctors = (cast(immutable(ModuleInfo)**).malloc(len * (void*).sizeof)); ctors = (cast(immutable(ModuleInfo)**).malloc(len * (void*).sizeof));
ctoridx = 0; ctoridx = 0;
foreach (int idx, m; _modules) foreach (idx, m; _modules)
{ {
if (m.flags & relevantFlags) if (m.flags & relevantFlags)
{ {
...@@ -582,8 +582,8 @@ struct ModuleGroup ...@@ -582,8 +582,8 @@ struct ModuleGroup
} }
// initialize the initial edges // initialize the initial edges
foreach (int i, ref v; initialEdges) foreach (i, ref v; initialEdges)
v = i; v = cast(int)i;
bool sort(ref immutable(ModuleInfo)*[] ctors, uint mask) bool sort(ref immutable(ModuleInfo)*[] ctors, uint mask)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment