Fix #125 – Nested class context pointer invalid (D1).

Patch originally by Alexey Prokhin, thanks.
This commit is contained in:
David Nadlinger 2012-06-24 16:18:47 +02:00
parent 67f12fe8b5
commit cef19fb225
2 changed files with 23 additions and 11 deletions

View file

@ -725,13 +725,6 @@ void DtoDefineFunction(FuncDeclaration* fd)
fd->vthis->ir.irParam->isVthis = true; fd->vthis->ir.irParam->isVthis = true;
DtoDwarfLocalVariable(thismem, fd->vthis); DtoDwarfLocalVariable(thismem, fd->vthis);
#if DMDV1
if (fd->vthis->nestedref)
{
fd->nestedVars.insert(fd->vthis);
}
#endif
} }
// give the 'nestArg' storage // give the 'nestArg' storage
@ -790,12 +783,18 @@ void DtoDefineFunction(FuncDeclaration* fd)
} }
} }
// need result variable? (nested)
#if DMDV1 #if DMDV1
// need result variable? (nested)
if (fd->vresult && fd->vresult->nestedref) { if (fd->vresult && fd->vresult->nestedref) {
Logger::println("nested vresult value: %s", fd->vresult->toChars()); Logger::println("nested vresult value: %s", fd->vresult->toChars());
fd->nestedVars.insert(fd->vresult); fd->nestedVars.insert(fd->vresult);
} }
if (fd->vthis && fd->vthis->nestedref && !fd->nestedVars.empty()) {
Logger::println("nested vthis value: %s", fd->vthis->toChars());
fd->nestedVars.insert(fd->vthis);
}
#endif #endif
FuncGen fg; FuncGen fg;

View file

@ -134,11 +134,22 @@ DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd, bool byref)
LLValue* val = irfunc->thisArg; LLValue* val = irfunc->thisArg;
if (cd->isClassDeclaration()) if (cd->isClassDeclaration())
val = DtoLoad(val); val = DtoLoad(val);
ctx = DtoLoad(DtoGEPi(val, 0, cd->vthis->ir.irField->index, ".vthis"));
#else #else
ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration();
LLValue* val = DtoLoad(irfunc->thisArg); LLValue* val = DtoLoad(irfunc->thisArg);
ctx = DtoGEPi(val, 0, cd->vthis->ir.irField->index, ".vthis");
if (!irfunc->frameType && vd->isThisDeclaration())
{
// If the only "nested" variable is the outer this pointer, we don't
// emit a normal context, but just store the this pointer - see
// GitHub #127.
return new DVarValue(astype, vd, ctx);
}
ctx = DtoLoad(ctx);
#endif #endif
ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis"));
} }
else if (irfunc->nestedVar) { else if (irfunc->nestedVar) {
ctx = irfunc->nestedVar; ctx = irfunc->nestedVar;
@ -311,12 +322,14 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym)
#if DMDV2 #if DMDV2
AggregateDeclaration* ad = irfunc->decl->isMember2(); AggregateDeclaration* ad = irfunc->decl->isMember2();
val = ad->isClassDeclaration() ? DtoLoad(irfunc->thisArg) : irfunc->thisArg; val = ad->isClassDeclaration() ? DtoLoad(irfunc->thisArg) : irfunc->thisArg;
if (!ad || !ad->vthis)
return llvm::UndefValue::get(getVoidPtrType());
#else #else
ClassDeclaration* ad = irfunc->decl->isMember2()->isClassDeclaration(); ClassDeclaration* ad = irfunc->decl->isMember2()->isClassDeclaration();
val = DtoLoad(irfunc->thisArg); val = DtoLoad(irfunc->thisArg);
#endif
if (!ad || !ad->vthis) if (!ad || !ad->vthis)
return llvm::UndefValue::get(getVoidPtrType()); return val;
#endif
val = DtoLoad(DtoGEPi(val, 0,ad->vthis->ir.irField->index, ".vthis")); val = DtoLoad(DtoGEPi(val, 0,ad->vthis->ir.irField->index, ".vthis"));
} }
else else