Fix ICE for ref/out params of opaque structs

Fixes dmd-testsuite's new compilable/test21668.d.
This commit is contained in:
Martin Kinkelin 2021-03-01 11:12:28 +01:00
parent 3abffca14c
commit 52bcbcc566
3 changed files with 25 additions and 13 deletions

View file

@ -183,14 +183,14 @@ struct X86TargetABI : TargetABI {
// * It is not a floating point type.
IrFuncTyArg *last = fty.args.back();
Type *lastTy = last->type->toBasetype();
unsigned sz = lastTy->size();
if (last->rewrite == &indirectByvalRewrite ||
(last->byref && !last->isByVal())) {
Logger::println("Putting last (byref) parameter in register");
last->attrs.addAttribute(LLAttribute::InReg);
} else if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) {
} else {
Type *lastTy = last->type->toBasetype();
auto sz = lastTy->size();
if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) {
// rewrite aggregates as integers to make inreg work
if (lastTy->ty == Tstruct || lastTy->ty == Tsarray) {
integerRewrite.applyTo(*last);
@ -202,6 +202,7 @@ struct X86TargetABI : TargetABI {
}
}
}
}
workaroundIssue1356(fty.args);

View file

@ -183,7 +183,16 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
loweredDType = merge(ltd);
} else if (passPointer) {
// ref/out
auto ts = loweredDType->toBasetype()->isTypeStruct();
if (ts && !ts->sym->members) {
// opaque struct
attrs.addAttribute(LLAttribute::NonNull);
#if LDC_LLVM_VER >= 1100
attrs.addAttribute(LLAttribute::NoUndef);
#endif
} else {
attrs.addDereferenceableAttr(loweredDType->size());
}
} else {
if (abi->passByVal(f, loweredDType)) {
// LLVM ByVal parameters are pointers to a copy in the function

View file

@ -152,6 +152,8 @@ void DtoDeleteArray(const Loc &loc, DValue *arr) {
unsigned DtoAlignment(Type *type) {
structalign_t alignment = type->alignment();
if (alignment == STRUCTALIGN_DEFAULT) {
auto ts = type->toBasetype()->isTypeStruct();
if (!ts || ts->sym->members) // not an opaque struct
alignment = type->alignsize();
}
return (alignment == STRUCTALIGN_DEFAULT ? 0 : alignment);