mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-02 16:11:08 +03:00
Fix ICE for ref/out params of opaque structs
Fixes dmd-testsuite's new compilable/test21668.d.
This commit is contained in:
parent
3abffca14c
commit
52bcbcc566
3 changed files with 25 additions and 13 deletions
|
@ -183,22 +183,23 @@ struct X86TargetABI : TargetABI {
|
||||||
// * It is not a floating point type.
|
// * It is not a floating point type.
|
||||||
|
|
||||||
IrFuncTyArg *last = fty.args.back();
|
IrFuncTyArg *last = fty.args.back();
|
||||||
Type *lastTy = last->type->toBasetype();
|
|
||||||
unsigned sz = lastTy->size();
|
|
||||||
|
|
||||||
if (last->rewrite == &indirectByvalRewrite ||
|
if (last->rewrite == &indirectByvalRewrite ||
|
||||||
(last->byref && !last->isByVal())) {
|
(last->byref && !last->isByVal())) {
|
||||||
Logger::println("Putting last (byref) parameter in register");
|
Logger::println("Putting last (byref) parameter in register");
|
||||||
last->attrs.addAttribute(LLAttribute::InReg);
|
last->attrs.addAttribute(LLAttribute::InReg);
|
||||||
} else if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) {
|
} else {
|
||||||
// rewrite aggregates as integers to make inreg work
|
Type *lastTy = last->type->toBasetype();
|
||||||
if (lastTy->ty == Tstruct || lastTy->ty == Tsarray) {
|
auto sz = lastTy->size();
|
||||||
integerRewrite.applyTo(*last);
|
if (!lastTy->isfloating() && (sz == 1 || sz == 2 || sz == 4)) {
|
||||||
// undo byval semantics applied via passByVal() returning true
|
// rewrite aggregates as integers to make inreg work
|
||||||
last->byref = false;
|
if (lastTy->ty == Tstruct || lastTy->ty == Tsarray) {
|
||||||
last->attrs.clear();
|
integerRewrite.applyTo(*last);
|
||||||
|
// undo byval semantics applied via passByVal() returning true
|
||||||
|
last->byref = false;
|
||||||
|
last->attrs.clear();
|
||||||
|
}
|
||||||
|
last->attrs.addAttribute(LLAttribute::InReg);
|
||||||
}
|
}
|
||||||
last->attrs.addAttribute(LLAttribute::InReg);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,16 @@ llvm::FunctionType *DtoFunctionType(Type *type, IrFuncTy &irFty, Type *thistype,
|
||||||
loweredDType = merge(ltd);
|
loweredDType = merge(ltd);
|
||||||
} else if (passPointer) {
|
} else if (passPointer) {
|
||||||
// ref/out
|
// ref/out
|
||||||
attrs.addDereferenceableAttr(loweredDType->size());
|
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 {
|
} else {
|
||||||
if (abi->passByVal(f, loweredDType)) {
|
if (abi->passByVal(f, loweredDType)) {
|
||||||
// LLVM ByVal parameters are pointers to a copy in the function
|
// LLVM ByVal parameters are pointers to a copy in the function
|
||||||
|
|
|
@ -152,7 +152,9 @@ void DtoDeleteArray(const Loc &loc, DValue *arr) {
|
||||||
unsigned DtoAlignment(Type *type) {
|
unsigned DtoAlignment(Type *type) {
|
||||||
structalign_t alignment = type->alignment();
|
structalign_t alignment = type->alignment();
|
||||||
if (alignment == STRUCTALIGN_DEFAULT) {
|
if (alignment == STRUCTALIGN_DEFAULT) {
|
||||||
alignment = type->alignsize();
|
auto ts = type->toBasetype()->isTypeStruct();
|
||||||
|
if (!ts || ts->sym->members) // not an opaque struct
|
||||||
|
alignment = type->alignsize();
|
||||||
}
|
}
|
||||||
return (alignment == STRUCTALIGN_DEFAULT ? 0 : alignment);
|
return (alignment == STRUCTALIGN_DEFAULT ? 0 : alignment);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue