Skip to content

Commit

Permalink
Merge pull request #1627 from 9rnsr/fix9453
Browse files Browse the repository at this point in the history
Issue 9453 - ice(symbol.c) with slice on temporary
  • Loading branch information
WalterBright committed Feb 6, 2013
2 parents 71f4fc8 + 6e2f1ec commit d9b2397
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
31 changes: 27 additions & 4 deletions src/dsymbol.c
Expand Up @@ -1320,6 +1320,9 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
*/
return NULL;

while (ce->op == TOKcomma)
ce = ((CommaExp *)ce)->e2;

/* If we are indexing into an array that is really a type
* tuple, rewrite this as an index into a type tuple and
* try again.
Expand Down Expand Up @@ -1370,6 +1373,29 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
return NULL;
s = s->toAlias();

if (ce->op != TOKvar)
{
/* Even if opDollar is needed, 'ce' should be evaluate only once. So
* Rewrite:
* ce.opIndex( ... use of $ ... )
* ce.opSlice( ... use of $ ... )
* as:
* (ref __dop = ce, __dop).opIndex( ... __dop.opDollar ...)
* (ref __dop = ce, __dop).opSlice( ... __dop.opDollar ...)
*/
Identifier *id = Lexer::uniqueId("__dop");
ExpInitializer *ei = new ExpInitializer(loc, ce);
VarDeclaration *v = new VarDeclaration(loc, NULL, id, ei);
v->storage_class |= STCctfe | STCforeach | STCref;
DeclarationExp *de = new DeclarationExp(loc, v);
VarExp *ve = new VarExp(loc, v);
v->semantic(sc);
de->type = ce->type;
ve->type = ce->type;
((UnaExp *)exp)->e1 = new CommaExp(loc, de, ve);
ce = ve;
}

Expression *e = NULL;
// Check for multi-dimensional opDollar(dim) template.
if (TemplateDeclaration *td = s->isTemplateDeclaration())
Expand All @@ -1378,14 +1404,11 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
if (exp->op == TOKarray)
{
dim = ((ArrayExp *)exp)->currentDimension;
e = ((ArrayExp *)exp)->e1;
}
else if (exp->op == TOKslice)
{
dim = 0; // slices are currently always one-dimensional
e = ((SliceExp *)exp)->e1;
}
assert(e);

Objects *tdargs = new Objects();
Expression *edim = new IntegerExp(0, dim, Type::tsize_t);
Expand All @@ -1395,7 +1418,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
//TemplateInstance *ti = new TemplateInstance(loc, td, tdargs);
//ti->semantic(sc);

e = new DotTemplateInstanceExp(loc, e, td->ident, tdargs);
e = new DotTemplateInstanceExp(loc, ce, td->ident, tdargs);
}
else
{ /* opDollar exists, but it's not a template.
Expand Down
23 changes: 23 additions & 0 deletions test/runnable/opover2.d
Expand Up @@ -922,6 +922,28 @@ void test19()
assert(foo[0 .. $] == [0, 0]);
}

/**************************************/
// 9453

struct Foo9453
{
static int ctor = 0;

this(string bar) { ++ctor; }

void opIndex(size_t i) const {}
void opSlice(size_t s, size_t e) const {}

size_t opDollar(int dim)() const if (dim == 0) { return 1; }
}

void test9453()
{
assert(Foo9453.ctor == 0); Foo9453("bar")[$-1];
assert(Foo9453.ctor == 1); Foo9453("bar")[0..$];
assert(Foo9453.ctor == 2);
}

/**************************************/

int main()
Expand All @@ -948,6 +970,7 @@ int main()
test8434();
test18();
test19();
test9453();

printf("Success\n");
return 0;
Expand Down

0 comments on commit d9b2397

Please sign in to comment.