mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-18 04:33:27 +01:00
Fix passing of a padded struct to a function
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<llvm::UndefValue>(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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user