Skip to content

Commit d24fc71

Browse files
committed
Win64 ABI: Treat dynamic arrays and delegates as structs.
I.e., pass them explicitly ByVal and return them via sret.
1 parent 01e3e37 commit d24fc71

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

gen/abi-win64.cpp

+14-9
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,16 @@ struct Win64TargetABI : TargetABI
4747
void rewriteArgument(IrFuncTy& fty, IrFuncTyArg& arg);
4848

4949
private:
50-
// Returns true if the D type is a composite (struct/static array/complex number).
51-
bool isComposite(Type* t)
50+
// Returns true if the D type is an aggregate:
51+
// * struct
52+
// * static/dynamic array
53+
// * delegate
54+
// * complex number
55+
bool isAggregate(Type* t)
5256
{
53-
return t->ty == Tstruct || t->ty == Tsarray
54-
|| t->iscomplex(); // treat complex numbers as structs too
57+
TY ty = t->ty;
58+
return ty == Tstruct || ty == Tsarray || ty == Tarray || ty == Tdelegate
59+
|| t->iscomplex();
5560
}
5661

5762
// Returns true if the D type can be bit-cast to an integer of the same size.
@@ -75,8 +80,9 @@ struct Win64TargetABI : TargetABI
7580
bool isPassedWithByvalSemantics(Type* t)
7681
{
7782
return
78-
// * structs/static arrays/complex numbers which can NOT be rewritten as integers
79-
(isComposite(t) && !canRewriteAsInt(t)) ||
83+
// * aggregates which can NOT be rewritten as integers
84+
// (size > 64 bits or not a power of 2)
85+
(isAggregate(t) && !canRewriteAsInt(t)) ||
8086
// * 80-bit real and ireal
8187
(realIs80bits() && (t->ty == Tfloat80 || t->ty == Timaginary80));
8288
}
@@ -116,8 +122,7 @@ bool Win64TargetABI::returnInArg(TypeFunction* tf)
116122
// * all POD types <= 64 bits and of a size that is a power of 2
117123
// (incl. 2x32-bit cfloat) are returned in a register (RAX, or
118124
// XMM0 for single float/ifloat/double/idouble)
119-
// * all other structs/static arrays/complex numbers and 80-bit
120-
// real/ireal are returned via struct-return (sret)
125+
// * all other types are returned via struct-return (sret)
121126
return (rt->ty == Tstruct && !((TypeStruct*)rt)->sym->isPOD())
122127
|| isPassedWithByvalSemantics(rt);
123128
}
@@ -165,7 +170,7 @@ void Win64TargetABI::rewriteArgument(IrFuncTy& fty, IrFuncTyArg& arg)
165170
.add(LDC_ATTRIBUTE(NoAlias))
166171
.add(LDC_ATTRIBUTE(NoCapture));
167172
}
168-
else if (isComposite(t) && canRewriteAsInt(t) && !IntegerRewrite::isObsoleteFor(originalLType))
173+
else if (isAggregate(t) && canRewriteAsInt(t) && !IntegerRewrite::isObsoleteFor(originalLType))
169174
{
170175
arg.rewrite = &integerRewrite;
171176
arg.ltype = integerRewrite.type(arg.type, arg.ltype);

0 commit comments

Comments
 (0)