diff --git a/src/toir.c b/src/toir.c index 63bf7f3dde05..5a9cd5532b1d 100644 --- a/src/toir.c +++ b/src/toir.c @@ -96,14 +96,36 @@ elem *getEthis(Loc loc, IRState *irs, Dsymbol *fd) elem *ethis; FuncDeclaration *thisfd = irs->getFunc(); Dsymbol *fdparent = fd->toParent2(); + Dsymbol *fdp = fdparent; + + /* These two are compiler generated functions for the in and out contracts, + * and are called from an overriding function, not just the one they're + * nested inside, so this hack is so they'll pass + */ + if (fdparent != thisfd && (fd->ident == Id::require || fd->ident == Id::ensure)) + { + FuncDeclaration *fdthis = thisfd; + for (size_t i = 0; ; ) + { + if (i == fdthis->foverrides.dim) + { + if (i == 0) + break; + fdthis = fdthis->foverrides[0]; + i = 0; + continue; + } + if (fdthis->foverrides[i] == fdp) + { + fdparent = thisfd; + break; + } + i++; + } + } //printf("[%s] getEthis(thisfd = '%s', fd = '%s', fdparent = '%s')\n", loc.toChars(), thisfd->toPrettyChars(), fd->toPrettyChars(), fdparent->toPrettyChars()); - if (fdparent == thisfd || - /* These two are compiler generated functions for the in and out contracts, - * and are called from an overriding function, not just the one they're - * nested inside, so this hack is so they'll pass - */ - fd->ident == Id::require || fd->ident == Id::ensure) + if (fdparent == thisfd) { /* Going down one nesting level, i.e. we're calling * a nested function from its enclosing function. @@ -191,7 +213,7 @@ elem *getEthis(Loc loc, IRState *irs, Dsymbol *fd) if (!ad) { Lnoframe: - irs->getFunc()->error(loc, "cannot get frame pointer to %s", fd->toChars()); + irs->getFunc()->error(loc, "cannot get frame pointer to %s", fd->toPrettyChars()); return el_long(TYnptr, 0); // error recovery } ClassDeclaration *cd = ad->isClassDeclaration(); diff --git a/test/runnable/testcontracts.d b/test/runnable/testcontracts.d index b5114be795db..435bd2bc262d 100644 --- a/test/runnable/testcontracts.d +++ b/test/runnable/testcontracts.d @@ -356,6 +356,40 @@ class Foo5204 : IFoo5204 Foo5204 bar() { return null; } } +/*******************************************/ +// 6417 + +class Bug6417 +{ + void bar() + in + { + int i = 14; + assert(i == 14); + auto dg = (){ + //printf("in: i = %d\n", i); + assert(i == 14, "in contract failure"); + }; + dg(); + } + out + { + int j = 10; + assert(j == 10); + auto dg = (){ + //printf("out: j = %d\n", j); + assert(j == 10, "out contract failure"); + }; + dg(); + } + body {} +} + +void test6417() +{ + (new Bug6417).bar(); +} + /*******************************************/ // 7218 @@ -647,6 +681,7 @@ int main() test8(); test9(); test4785(); + test6417(); test7218(); test8073(); test8093();