diff --git a/gen/abi-generic.h b/gen/abi-generic.h index 83a883c4..f55afa04 100644 --- a/gen/abi-generic.h +++ b/gen/abi-generic.h @@ -10,18 +10,16 @@ struct RemoveStructPadding : ABIRewrite { /// get a rewritten value back to its original form virtual LLValue* get(Type* dty, DValue* v) { LLValue* lval = DtoAlloca(dty, ".rewritetmp"); - - // Make sure the padding is zero, so struct comparisons work. - // TODO: Only do this if there's padding, and/or only initialize padding. - DtoMemSetZero(lval, DtoConstSize_t(getTypePaddedSize(DtoType(dty)))); - - DtoPaddedStruct(dty->toBasetype(), v->getRVal(), lval); + getL(dty, v, lval); return lval; } /// get a rewritten value back to its original form and store result in provided lvalue /// this one is optional and defaults to calling the one above virtual void getL(Type* dty, DValue* v, llvm::Value* lval) { + // Make sure the padding is zero, so struct comparisons work. + // TODO: Only do this if there's padding, and/or only initialize padding. + DtoMemSetZero(lval, DtoConstSize_t(getTypePaddedSize(DtoType(dty)))); DtoPaddedStruct(dty->toBasetype(), v->getRVal(), lval); } diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index 0839679b..01593675 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -653,10 +653,12 @@ bool X86_64TargetABI::passByVal(Type* t) { // Structs passed or returned in registers are passed here // to get their padding removed (if necessary). void X86_64TargetABI::fixup_D(IrFuncTyArg& arg) { - assert(arg.type->toBasetype()->ty == Tstruct); - LLType* abiTy = DtoUnpaddedStructType(arg.type->toBasetype()); - - if (abiTy && abiTy != arg.ltype) { + TypeStruct *type = (TypeStruct*)arg.type->toBasetype(); + assert(type->ty == Tstruct); + if (type->alignsize() != 1) { + // TODO: don't do this transformation if there's no padding + LLType* abiTy = DtoUnpaddedStructType(type); + assert(abiTy); arg.ltype = abiTy; arg.rewrite = &remove_padding; } diff --git a/gen/nested.cpp b/gen/nested.cpp index 973187ae..6c832872 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -258,9 +258,11 @@ LLValue* DtoResolveNestedContext(Loc loc, ClassDeclaration *decl, LLValue *value LLValue* nest = DtoNestedContext(loc, decl); // store into right location - size_t idx = decl->vthis->ir.irField->index; - LLValue* gep = DtoGEPi(value,0,idx,"tmp"); - DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep); + if (!llvm::dyn_cast(nest)) { + size_t idx = decl->vthis->ir.irField->index; + LLValue* gep = DtoGEPi(value,0,idx,".vthis"); + DtoStore(DtoBitCast(nest, gep->getType()->getContainedType(0)), gep); + } } LLValue* DtoNestedContext(Loc loc, Dsymbol* sym) diff --git a/gen/statements.cpp b/gen/statements.cpp index 04507de9..4333fa06 100644 --- a/gen/statements.cpp +++ b/gen/statements.cpp @@ -115,22 +115,24 @@ void ReturnStatement::toIR(IRState* p) else { LLValue* v; + DValue* dval = exp->toElem(p); + + // call postblit if necessary + callPostblitHelper(loc, exp, dval->getRVal()); + if (!exp && (p->topfunc() == p->mainFunc)) v = LLConstant::getNullValue(p->mainFunc->getReturnType()); else // do abi specific transformations on the return value #if DMDV2 - v = p->func()->type->fty.putRet(exp->type, exp->toElem(p), p->func()->type->isref); + v = p->func()->type->fty.putRet(exp->type, dval, p->func()->type->isref); #else - v = p->func()->type->fty.putRet(exp->type, exp->toElem(p)); + v = p->func()->type->fty.putRet(exp->type, dval); #endif if (Logger::enabled()) Logger::cout() << "return value is '" <<*v << "'\n"; - // call postblit if necessary - callPostblitHelper(loc, exp, v); - IrFunction* f = p->func(); // Hack around LDC assuming structs and static arrays are in memory: // If the function returns a struct or a static array, and the return