Skip to content

Commit

Permalink
Merge pull request #3371 from 9rnsr/fix12334
Browse files Browse the repository at this point in the history
Issue 12334 - Cannot access frame pointer of nested class from inside lambda
  • Loading branch information
AndrejMitrovic committed Mar 13, 2014
2 parents 2085bcf + b0515c5 commit 87b8f78
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 17 deletions.
55 changes: 38 additions & 17 deletions src/expression.c
Expand Up @@ -4760,7 +4760,8 @@ Expression *NewExp::semantic(Scope *sc)
nargs = arguments ? arguments->dim : 0;

if (thisexp && tb->ty != Tclass)
{ error("e.new is only for allocating nested classes, not %s", tb->toChars());
{
error("e.new is only for allocating nested classes, not %s", tb->toChars());
goto Lerr;
}

Expand All @@ -4771,26 +4772,31 @@ Expression *NewExp::semantic(Scope *sc)
if (cd->scope)
cd->semantic(NULL);
if (cd->isInterfaceDeclaration())
{ error("cannot create instance of interface %s", cd->toChars());
{
error("cannot create instance of interface %s", cd->toChars());
goto Lerr;
}
else if (cd->isAbstract())
{ error("cannot create instance of abstract class %s", cd->toChars());
{
error("cannot create instance of abstract class %s", cd->toChars());
for (size_t i = 0; i < cd->vtbl.dim; i++)
{ FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration();
{
FuncDeclaration *fd = cd->vtbl[i]->isFuncDeclaration();
if (fd && fd->isAbstract())
errorSupplemental(loc, "function '%s' is not implemented", fd->toFullSignature());
}
goto Lerr;
}

if (cd->noDefaultCtor && !nargs && !cd->defaultCtor)
{ error("default construction is disabled for type %s", cd->type->toChars());
{
error("default construction is disabled for type %s", cd->type->toChars());
goto Lerr;
}
checkDeprecated(sc, cd);
if (cd->isNested())
{ /* We need a 'this' pointer for the nested class.
{
/* We need a 'this' pointer for the nested class.
* Ensure we have the right one.
*/
Dsymbol *s = cd->toParent2();
Expand All @@ -4805,7 +4811,8 @@ Expression *NewExp::semantic(Scope *sc)
// Supply an implicit 'this' and try again
thisexp = new ThisExp(loc);
for (Dsymbol *sp = sc->parent; 1; sp = sp->parent)
{ if (!sp)
{
if (!sp)
{
error("outer class %s 'this' needed to 'new' nested class %s", cdn->toChars(), cd->toChars());
goto Lerr;
Expand All @@ -4825,13 +4832,15 @@ Expression *NewExp::semantic(Scope *sc)
{
//printf("cdthis = %s\n", cdthis->toChars());
if (cdthis != cdn && !cdn->isBaseOf(cdthis, NULL))
{ error("'this' for nested class must be of type %s, not %s", cdn->toChars(), thisexp->type->toChars());
{
error("'this' for nested class must be of type %s, not %s", cdn->toChars(), thisexp->type->toChars());
goto Lerr;
}
}
}
else if (thisexp)
{ error("e.new is only for allocating nested classes");
{
error("e.new is only for allocating nested classes");
goto Lerr;
}
else if (fdn)
Expand All @@ -4847,13 +4856,18 @@ Expression *NewExp::semantic(Scope *sc)
error("outer function context of %s is needed to 'new' nested class %s", fdn->toPrettyChars(), cd->toPrettyChars());
goto Lerr;
}
else if (FuncLiteralDeclaration *fld = sp->isFuncLiteralDeclaration())
{
fld->tok = TOKdelegate;
}
}
}
else
assert(0);
}
else if (thisexp)
{ error("e.new is only for allocating nested classes");
{
error("e.new is only for allocating nested classes");
goto Lerr;
}

Expand Down Expand Up @@ -4884,7 +4898,8 @@ Expression *NewExp::semantic(Scope *sc)
else
{
if (nargs)
{ error("no constructor for %s", cd->toChars());
{
error("no constructor for %s", cd->toChars());
goto Lerr;
}
}
Expand Down Expand Up @@ -4912,7 +4927,8 @@ Expression *NewExp::semantic(Scope *sc)
else
{
if (newargs && newargs->dim)
{ error("no allocator for %s", cd->toChars());
{
error("no allocator for %s", cd->toChars());
goto Lerr;
}
}
Expand All @@ -4924,7 +4940,8 @@ Expression *NewExp::semantic(Scope *sc)
if (sd->scope)
sd->semantic(NULL);
if (sd->noDefaultCtor && !nargs)
{ error("default construction is disabled for type %s", sd->type->toChars());
{
error("default construction is disabled for type %s", sd->type->toChars());
goto Lerr;
}

Expand All @@ -4951,7 +4968,8 @@ Expression *NewExp::semantic(Scope *sc)
else
{
if (newargs && newargs->dim)
{ error("no allocator for %s", sd->toChars());
{
error("no allocator for %s", sd->toChars());
goto Lerr;
}
}
Expand Down Expand Up @@ -5015,13 +5033,15 @@ Expression *NewExp::semantic(Scope *sc)
Dsymbol *s = tn->toDsymbol(sc);
AggregateDeclaration *ad = s ? s->isAggregateDeclaration() : NULL;
if (ad && ad->noDefaultCtor)
{ error("default construction is disabled for type %s", tb->nextOf()->toChars());
{
error("default construction is disabled for type %s", tb->nextOf()->toChars());
goto Lerr;
}
for (size_t i = 0; i < nargs; i++)
{
if (tb->ty != Tarray)
{ error("too many arguments for array");
{
error("too many arguments for array");
goto Lerr;
}

Expand All @@ -5030,7 +5050,8 @@ Expression *NewExp::semantic(Scope *sc)
arg = arg->implicitCastTo(sc, Type::tsize_t);
arg = arg->optimize(WANTvalue);
if (arg->op == TOKint64 && (sinteger_t)arg->toInteger() < 0)
{ error("negative array index %s", arg->toChars());
{
error("negative array index %s", arg->toChars());
goto Lerr;
}
(*arguments)[i] = arg;
Expand Down
20 changes: 20 additions & 0 deletions test/runnable/nested.d
Expand Up @@ -2337,6 +2337,25 @@ void test11297() {
xreduce!foo11297();
}

/*******************************************/
// 12234

void test12234()
{
class B
{
int a;
this(int aa) { a = aa; }
}
auto foo = {
return new B(1);
};
static assert(is(typeof(foo) == delegate));

auto b = foo();
assert(b.a == 1);
}

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

int main()
Expand Down Expand Up @@ -2425,6 +2444,7 @@ int main()
test9244();
test11385();
test11297();
test12234();

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

0 comments on commit 87b8f78

Please sign in to comment.