mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 19:06:02 +03:00
Handle new extern(C) structs with size 0
The linkage now (2.098) also affects the size of empty structs - e.g., 1 for extern(C++), 0 for Posix extern(C), 4 for MSVC extern(C). This also affects beauties like `extern(C) struct S { double[0] a; }`, as tested by dmd-testsuite's runnable/ldc_cabi1.d, which is hereby fixed for Posix - don't try to GEP into an empty LL struct.
This commit is contained in:
parent
4fd476da9a
commit
db4867d437
2 changed files with 17 additions and 14 deletions
|
@ -1844,27 +1844,32 @@ LLValue *DtoIndexAggregate(LLValue *src, AggregateDeclaration *ad,
|
|||
// ourselves, DtoType below would be enough.
|
||||
DtoResolveDsymbol(ad);
|
||||
|
||||
// Cast the pointer we got to the canonical struct type the indices are
|
||||
// based on.
|
||||
LLType *st = DtoType(ad->type);
|
||||
if (ad->isStructDeclaration()) {
|
||||
st = getPtrToType(st);
|
||||
}
|
||||
src = DtoBitCast(src, st);
|
||||
|
||||
// Look up field to index and any offset to apply.
|
||||
// Look up field to index or offset to apply.
|
||||
unsigned fieldIndex;
|
||||
unsigned byteOffset;
|
||||
auto irTypeAggr = getIrType(ad->type)->isAggr();
|
||||
assert(irTypeAggr);
|
||||
irTypeAggr->getMemberLocation(vd, fieldIndex, byteOffset);
|
||||
|
||||
LLValue *val = DtoGEP(src, 0, fieldIndex);
|
||||
|
||||
LLValue *val = src;
|
||||
if (byteOffset) {
|
||||
// Cast to void* to apply byte-wise offset.
|
||||
assert(fieldIndex == 0);
|
||||
// Cast to void* to apply byte-wise offset from object start.
|
||||
val = DtoBitCast(val, getVoidPtrType());
|
||||
val = DtoGEP1(val, byteOffset);
|
||||
} else {
|
||||
if (ad->structsize == 0) { // can happen for extern(C) structs
|
||||
assert(fieldIndex == 0);
|
||||
} else {
|
||||
// Cast the pointer we got to the canonical struct type the indices are
|
||||
// based on.
|
||||
LLType *st = DtoType(ad->type);
|
||||
if (ad->isStructDeclaration()) {
|
||||
st = getPtrToType(st);
|
||||
}
|
||||
val = DtoBitCast(val, st);
|
||||
val = DtoGEP(val, 0, fieldIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Cast the (possibly void*) pointer to the canonical variable type.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue