Skip to content

Commit

Permalink
fix Issue 11545 - Aggregate function literal member should not have a…
Browse files Browse the repository at this point in the history
…ccess to enclosing scope
  • Loading branch information
9rnsr committed Mar 14, 2014
1 parent 85220de commit 180a6aa
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 24 deletions.
2 changes: 2 additions & 0 deletions src/declaration.h
Expand Up @@ -720,6 +720,8 @@ class FuncLiteralDeclaration : public FuncDeclaration
Dsymbol *syntaxCopy(Dsymbol *);
bool isNested();
bool isVirtual();
bool addPreInvariant();
bool addPostInvariant();

FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
const char *kind();
Expand Down
2 changes: 1 addition & 1 deletion src/expression.c
Expand Up @@ -224,7 +224,7 @@ bool isNeedThisScope(Scope *sc, Declaration *d)
}
if (FuncDeclaration *f = s->isFuncDeclaration())
{
if (f->isFuncLiteralDeclaration())
if (f->isFuncLiteralDeclaration() && f->isNested())
continue;
if (f->isMember2())
break;
Expand Down
52 changes: 33 additions & 19 deletions src/func.c
Expand Up @@ -1290,18 +1290,24 @@ void FuncDeclaration::semantic3(Scope *sc)
sc2->fieldinit = NULL;
sc2->fieldinit_dim = 0;

// Declare 'this'
AggregateDeclaration *ad = isThis();
if (ad)
if (AggregateDeclaration *ad = isMember2())
{
if (isFuncLiteralDeclaration() && isNested() && !sc->intypeof)
FuncLiteralDeclaration *fld = isFuncLiteralDeclaration();
if (fld && !sc->intypeof)
{
error("function literals cannot be class members");
return;
if (fld->tok == TOKreserved)
fld->tok = TOKfunction;
if (isNested())
{
error("cannot be class members");
return;
}
}
else
assert(!isNested() || sc->intypeof); // can't be both member and nested
assert(!isNested() || sc->intypeof); // can't be both member and nested
}

// Declare 'this'
AggregateDeclaration *ad = isThis();
vthis = declareThis(sc2, ad);

// Declare hidden variable _arguments[] and _argptr
Expand Down Expand Up @@ -2194,9 +2200,9 @@ void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)

VarDeclaration *FuncDeclaration::declareThis(Scope *sc, AggregateDeclaration *ad)
{
if (ad)
{ VarDeclaration *v;

if (ad && !isFuncLiteralDeclaration())
{
VarDeclaration *v;
{
assert(ad->handle);
Type *thandle = ad->handle;
Expand Down Expand Up @@ -3147,11 +3153,10 @@ LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident)
*/

AggregateDeclaration *FuncDeclaration::isThis()
{ AggregateDeclaration *ad;

{
//printf("+FuncDeclaration::isThis() '%s'\n", toChars());
ad = NULL;
if ((storage_class & STCstatic) == 0)
AggregateDeclaration *ad = NULL;
if ((storage_class & STCstatic) == 0 && !isFuncLiteralDeclaration())
{
ad = isMember2();
}
Expand All @@ -3160,13 +3165,12 @@ AggregateDeclaration *FuncDeclaration::isThis()
}

AggregateDeclaration *FuncDeclaration::isMember2()
{ AggregateDeclaration *ad;

{
//printf("+FuncDeclaration::isMember2() '%s'\n", toChars());
ad = NULL;
AggregateDeclaration *ad = NULL;
for (Dsymbol *s = this; s; s = s->parent)
{
//printf("\ts = '%s', parent = '%s', kind = %s\n", s->toChars(), s->parent->toChars(), s->parent->kind());
//printf("\ts = '%s', parent = '%s', kind = %s\n", s->toChars(), s->parent->toChars(), s->parent->kind());
ad = s->isMember();
if (ad)
{
Expand Down Expand Up @@ -4192,6 +4196,16 @@ bool FuncLiteralDeclaration::isVirtual()
return false;
}

bool FuncLiteralDeclaration::addPreInvariant()
{
return false;
}

bool FuncLiteralDeclaration::addPostInvariant()
{
return false;
}

const char *FuncLiteralDeclaration::kind()
{
// GCC requires the (char*) casts
Expand Down
20 changes: 20 additions & 0 deletions test/fail_compilation/fail11545.d
@@ -0,0 +1,20 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail11545.d(14): Error: need 'this' for 'x' of type 'int'
fail_compilation/fail11545.d(18): Error: need 'this' for 'x' of type 'int'
---
*/

class C
{
int x = 42;

int function() f1 = function() {
return x;
};

int function() f2 = {
return x;
};
}
4 changes: 2 additions & 2 deletions test/fail_compilation/fail120.d
@@ -1,8 +1,8 @@
/*
TEST_OUTPUT:
---
fail_compilation/fail120.d(12): Error: delegate fail120.Foo.__lambda4 function literals cannot be class members
fail_compilation/fail120.d(13): Error: delegate fail120.Foo.__lambda5 function literals cannot be class members
fail_compilation/fail120.d(12): Error: need 'this' for 'nodes' of type 'int[2]'
fail_compilation/fail120.d(13): Error: need 'this' for 'nodes' of type 'int[2]'
---
*/

Expand Down
21 changes: 19 additions & 2 deletions test/fail_compilation/ice10259.d
@@ -1,7 +1,8 @@
/*
TEST_OUTPUT:
---
fail_compilation/ice10259.d(12): Error: delegate ice10259.D.__lambda3 function literals cannot be class members
fail_compilation/ice10259.d(13): Error: circular reference to 'ice10259.D.d'
fail_compilation/ice10259.d(13): called from here: (*function () => x)()
fail_compilation/ice10259.d(15): Error: variable ice10259.x : Unable to initialize enum with class or pointer to struct. Use static const variable instead.
---
*/
Expand All @@ -11,5 +12,21 @@ class D
int x;
D d = { auto x = new D(); return x; }();
}

enum x = new D;


/*
TEST_OUTPUT:
---
fail_compilation/ice10259.d(30): Error: circular reference to 'ice10259.D2.d'
fail_compilation/ice10259.d(30): called from here: (*function () => x)()
fail_compilation/ice10259.d(32): Error: variable ice10259.x2 : Unable to initialize enum with class or pointer to struct. Use static const variable instead.
---
*/

class D2
{
int x;
D2 d = function { auto x = new D2(); return x; }();
}
enum x2 = new D2;
20 changes: 20 additions & 0 deletions test/runnable/funclit.d
Expand Up @@ -952,6 +952,25 @@ C11230 visit11230()
return null;
}

/***************************************************/
// 10336

struct S10336
{
template opDispatch(string name)
{
enum opDispatch = function(int x) {
return x;
};
}
}

void test10336()
{
S10336 s;
assert(s.hello(12) == 12);
}

/***************************************************/
// 11661

Expand Down Expand Up @@ -1009,6 +1028,7 @@ int main()
test9928();
test10133();
test10288();
test10336();
test11661();

printf("Success\n");
Expand Down

0 comments on commit 180a6aa

Please sign in to comment.