Skip to content

Commit

Permalink
Merge branch 'master' of github.com:D-Programming-Language/dmd
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed Nov 6, 2012
2 parents 0b6c74b + 89b335e commit ca52b17
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 27 deletions.
3 changes: 1 addition & 2 deletions src/doc.c
@@ -1,4 +1,3 @@

// Compiler implementation of the D programming language
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
Expand Down Expand Up @@ -191,7 +190,7 @@ DDOC_PARAM_ID = $(TD $0)\n\
DDOC_PARAM_DESC = $(TD $0)\n\
DDOC_BLANKLINE = $(BR)$(BR)\n\
\n\
DDOC_ANCHOR = <a name=\"$1\"></a>\n\
DDOC_ANCHOR = <a name=\"$0\"></a>\n\
DDOC_PSYMBOL = $(U $0)\n\
DDOC_KEYWORD = $(B $0)\n\
DDOC_PARAM = $(I $0)\n\
Expand Down
48 changes: 26 additions & 22 deletions src/statement.c
Expand Up @@ -2487,6 +2487,7 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
if (arg->type)
{
arg->type = arg->type->semantic(loc, sc);
arg->type = arg->type->addStorageClass(arg->storageClass);
lwr = lwr->implicitCastTo(sc, arg->type);
upr = upr->implicitCastTo(sc, arg->type);
}
Expand All @@ -2499,13 +2500,15 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
{
/* Just picking the first really isn't good enough.
*/
arg->type = lwr->type->mutableOf();
arg->type = lwr->type;
arg->type = arg->type->addStorageClass(arg->storageClass);
}
else
{
AddExp ea(loc, lwr, upr);
Expression *e = ea.typeCombine(sc);
arg->type = ea.type->mutableOf();
arg->type = ea.type;
arg->type = arg->type->addStorageClass(arg->storageClass);
lwr = ea.e1;
upr = ea.e2;
}
Expand All @@ -2520,14 +2523,7 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
*/

ExpInitializer *ie = new ExpInitializer(loc, (op == TOKforeach) ? lwr : upr);
#if (BUG6652 == 1 || BUG6652 == 2)
key = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), ie);
#else
if (arg->storageClass & STCref)
key = new VarDeclaration(loc, arg->type, arg->ident, ie);
else
key = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), ie);
#endif
key = new VarDeclaration(loc, arg->type->mutableOf(), Lexer::uniqueId("__key"), ie);

Identifier *id = Lexer::uniqueId("__limit");
ie = new ExpInitializer(loc, (op == TOKforeach) ? upr : lwr);
Expand Down Expand Up @@ -2575,26 +2571,34 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
increment = new PreExp(TOKpreplusplus, loc, new VarExp(loc, key));

#if (BUG6652 == 1 || BUG6652 == 2)
if (arg->storageClass & STCref)
ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
v->storage_class |= STCforeach | STCref | (arg->storageClass & STCref ? 0 : STCbug6652);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
#else
if ((arg->storageClass & STCref) && arg->type->equals(key->type))
{
AliasDeclaration *v = new AliasDeclaration(loc, arg->ident, key);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
TypeIdentifier *tname = new TypeIdentifier(s->loc, key->ident);
AliasDeclaration *ad = new AliasDeclaration(loc, arg->ident, tname);
body = new CompoundStatement(loc, new ExpStatement(loc, ad), body);
}
else
{
ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
v->storage_class |= STCforeach | STCref | STCbug6652;
ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
v->storage_class |= STCforeach | (arg->storageClass & STCref);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
}
#else
if (!(arg->storageClass & STCref))
#endif
if (arg->storageClass & STCref)
{
ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
if (!key->type->invariantOf()->equals(arg->type->invariantOf()) ||
!MODimplicitConv(key->type->mod, arg->type->mod))
{
error("argument type mismatch, %s to ref %s",
key->type->toChars(), arg->type->toChars());
}
}
#endif

ForStatement *fs = new ForStatement(loc, forinit, cond, increment, body);
s = fs->semantic(sc);
Expand Down
37 changes: 34 additions & 3 deletions test/runnable/foreach5.d
Expand Up @@ -189,15 +189,45 @@ void test3187()
/***************************************/
// 4090

void test4090()
void test4090a()
{
double[10] arr;
double[10] arr = 1;
double tot = 0;

static assert(!__traits(compiles, {
foreach (immutable ref x; arr) {}
}));
foreach (const ref x; arr)
{
static assert(is(typeof(x) == const double));
tot += x;
}
foreach (immutable x; arr)
{
static assert(is(typeof(x) == immutable double));
tot += x;
}
assert(tot == 1*10 + 1*10);
}

void test4090b()
{
int tot = 0;

static assert(!__traits(compiles, {
foreach (immutable ref x; 1..11) {}
}));
foreach (const ref x; 1..11)
{
static assert(is(typeof(x) == const int));
tot += x;
}
foreach (immutable x; 1..11)
{
static assert(is(typeof(x) == immutable int));
tot += x;
}
assert(tot == 55 + 55);
}

/***************************************/
Expand Down Expand Up @@ -430,7 +460,8 @@ int main()
test2442();
test2443();
test3187();
test4090();
test4090a();
test4090b();
test5605();
test7004();
test7406();
Expand Down

0 comments on commit ca52b17

Please sign in to comment.