Skip to content

Commit

Permalink
Merge pull request #10009 from ibuclaw/dmd-cxx-19856
Browse files Browse the repository at this point in the history
[dmd-cxx] Fix Issue 19856 - [aApplycd2]: foreach (int) doesn't work on BigEndian targets
  • Loading branch information
ibuclaw committed Jun 9, 2019
2 parents 9746504 + 9fcce71 commit f8e38c0
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 16 deletions.
44 changes: 39 additions & 5 deletions src/statementsem.c
Original file line number Diff line number Diff line change
Expand Up @@ -773,16 +773,48 @@ class StatementSemanticVisitor : public Visitor
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))
Expand All @@ -809,8 +841,6 @@ class StatementSemanticVisitor : public Visitor
{
// 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)
Expand Down Expand Up @@ -908,6 +938,10 @@ class StatementSemanticVisitor : public Visitor
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
Expand Down
66 changes: 66 additions & 0 deletions test/compilable/b16976.d
Original file line number Diff line number Diff line change
@@ -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) { }
}
20 changes: 10 additions & 10 deletions test/compilable/interpret3.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand All @@ -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;
Expand All @@ -3482,22 +3482,22 @@ bool test3512()
{}

// _aApplyRdc2
foreach_reverse (int n, char c; dr)
foreach_reverse (ptrdiff_t n, char c; dr)
{
if (n == 4)
break;
assert(c != 'o');
}

// _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);
Expand Down
44 changes: 44 additions & 0 deletions test/fail_compilation/diag16976.d
Original file line number Diff line number Diff line change
@@ -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) {}
}
2 changes: 1 addition & 1 deletion test/fail_compilation/fail110.d
Original file line number Diff line number Diff line change
Expand Up @@ -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;;) {}
}

0 comments on commit f8e38c0

Please sign in to comment.