Skip to content

Commit

Permalink
Merge pull request #8941 from dlang/thewilsonator-patch-3
Browse files Browse the repository at this point in the history
 Fix issue 16976 - Do not convert blindly the size of an iterable
merged-on-behalf-of: Nicholas Wilson <thewilsonator@users.noreply.github.com>
  • Loading branch information
dlang-bot committed Nov 15, 2018
2 parents 8f3f5d6 + 1003fe6 commit 0c1fdaf
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/dmd/statementsem.d
Expand Up @@ -1229,6 +1229,11 @@ private extern (C++) final class StatementSemanticVisitor : Visitor

if (dim == 2 && i == 0)
{
if (!p.type.isintegral())
{
fs.error("foreach: key cannot be of non-integral type `%s`", p.type.toChars());
goto case Terror;
}
var = new VarDeclaration(loc, p.type.mutableOf(), Identifier.generateId("__key"), null);
var.storage_class |= STC.temp | STC.foreach_;
if (var.storage_class & (STC.ref_ | STC.out_))
Expand Down Expand Up @@ -1256,6 +1261,11 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
}
fs.key.range = new IntRange(SignExtendedNumber(0), dimrange.imax);
}
else if (!Type.tsize_t.implicitConvTo(var.type))
{
fs.deprecation("foreach: loop index implicitly converted from `size_t` to `%s`",
fs.key.type.toChars());
}
}
else
{
Expand Down Expand Up @@ -1323,6 +1333,10 @@ private extern (C++) final class StatementSemanticVisitor : Visitor
fs.key = new VarDeclaration(loc, Type.tsize_t, idkey, null);
fs.key.storage_class |= STC.temp;
}
else if (fs.key.type.ty != Tsize_t)
{
tmp_length = new CastExp(loc, tmp_length, fs.key.type);
}
if (fs.op == TOK.foreach_reverse_)
fs.key._init = new ExpInitializer(loc, tmp_length);
else
Expand Down
23 changes: 23 additions & 0 deletions test/compilable/b16976.d
@@ -0,0 +1,23 @@
/* REQUIRED_ARGS: -m64
TEST_OUTPUT:
---
compilable/b16976.d(15): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
compilable/b16976.d(16): Deprecation: foreach: loop index implicitly converted from `size_t` to `int`
compilable/b16976.d(17): Deprecation: foreach: loop index implicitly converted from `size_t` to `char`
compilable/b16976.d(18): 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];

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) { }
}
18 changes: 18 additions & 0 deletions test/fail_compilation/diag16976.d
@@ -0,0 +1,18 @@
/* TEST_OUTPUT:
---
fail_compilation/diag16976.d(14): Error: foreach: key cannot be of non-integral type `float`
fail_compilation/diag16976.d(15): Error: foreach: key cannot be of non-integral type `float`
fail_compilation/diag16976.d(16): Error: foreach: key cannot be of non-integral type `float`
fail_compilation/diag16976.d(17): 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];
foreach(float f, i; dyn) {}
foreach(float f, i; sta) {}
foreach_reverse(float f, i; dyn) {}
foreach_reverse(float f, i; sta) {}
}
2 changes: 1 addition & 1 deletion test/fail_compilation/fail110.d
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 0c1fdaf

Please sign in to comment.