Skip to content
This repository has been archived by the owner on Jun 20, 2019. It is now read-only.

Commit

Permalink
Fix XBUG failures in nested.d from the testsuite
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuclaw committed Apr 12, 2015
1 parent c76a734 commit 84e7785
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 14 deletions.
5 changes: 5 additions & 0 deletions gcc/d/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2015-04-12 Iain Buclaw <ibuclaw@gdcproject.org>

* d-objfile.cc(get_decl_tree): Check and generate correct code for when
a non-local 'this' is accessed through a closure pointer.

2015-04-11 Johannes Pfau <johannespfau@gmail.com>

* d-objfile.cc(setup_symbol_storage): Mark functions without
Expand Down
34 changes: 27 additions & 7 deletions gcc/d/d-codegen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,25 +196,45 @@ get_decl_tree (Declaration *decl, FuncDeclaration *func)
else if (vd->parent != func && vd->isThisDeclaration() && func->isThis())
{
// Get the non-local 'this' value by going through parent link
// of nested classes.
// of nested classes, this routine pretty much undoes what
// getRightThis in the frontend removes from codegen.
AggregateDeclaration *ad = func->isThis();
tree this_tree = func->vthis->toSymbol()->Stree;

while (ad->isNested())
while (true)
{
Dsymbol *outer = ad->toParent2();
// Get the this->this parent link.
tree vthis_field = ad->vthis->toSymbol()->Stree;
this_tree = component_ref (build_deref (this_tree), vthis_field);

ad = outer->isAggregateDeclaration();
if (ad == NULL)
if (ad != NULL)
continue;

FuncDeclaration *fd = outer->isFuncDeclaration();
if (fd && fd->isThis())
{
gcc_assert (outer == vd->parent);
return this_tree;
ad = fd->isThis();

// If outer function creates a closure, then the 'this' value
// would be the closure pointer, and the real 'this' the first
// field of that closure.
FuncFrameInfo *ff = get_frameinfo (fd);
if (ff->creates_frame)
{
this_tree = build_nop (build_pointer_type (ff->frame_rec), this_tree);
this_tree = indirect_ref (ad->type->toCtype(), this_tree);
}

// Continue looking for the right 'this'
if (fd != vd->parent)
continue;
}
}

gcc_unreachable();
gcc_assert (outer == vd->parent);
return this_tree;
}
}
}

Expand Down
5 changes: 0 additions & 5 deletions gcc/d/dfrontend/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,7 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
{
//printf("rewriting e1 to %s's this\n", f->toChars());
n++;
#ifdef IN_GCC
if (n > 1)
e1 = new VarExp(loc, f->vthis);
#else
e1 = new VarExp(loc, f->vthis);
#endif
}
else
{
Expand Down
4 changes: 2 additions & 2 deletions gcc/testsuite/gdc.test/runnable/nested.d
Original file line number Diff line number Diff line change
Expand Up @@ -2439,8 +2439,8 @@ int main()
test32();
test33();
test34();
//test35(); // XBUG: Closure handling.
//test36(); // XBUG: Closure handling.
test35();
test36();
test37();
test38();
test39();
Expand Down

0 comments on commit 84e7785

Please sign in to comment.