Fix issue #2235 - IR struct packedness (#2247)

Unnaturally aligned aggregates were potentially not marked as packed,
leading to LLVM inserting additional padding and screwing up the memory
layout.
This commit is contained in:
kinke 2017-08-11 19:05:09 +02:00 committed by GitHub
parent ec9ffe29f1
commit ab37d5ba99
7 changed files with 45 additions and 65 deletions

View file

@ -1301,42 +1301,6 @@ void DtoSetFuncDeclIntrinsicName(TemplateInstance *ti, TemplateDeclaration *td,
////////////////////////////////////////////////////////////////////////////////
bool hasUnalignedFields(Type *t) {
t = t->toBasetype();
if (t->ty == Tsarray) {
assert(t->nextOf()->size() % t->nextOf()->alignsize() == 0);
return hasUnalignedFields(t->nextOf());
}
if (t->ty != Tstruct) {
return false;
}
TypeStruct *ts = static_cast<TypeStruct *>(t);
if (ts->unaligned) {
return (ts->unaligned == 2);
}
StructDeclaration *sym = ts->sym;
// go through all the fields and try to find something unaligned
ts->unaligned = 2;
for (unsigned i = 0; i < sym->fields.dim; i++) {
VarDeclaration *f = static_cast<VarDeclaration *>(sym->fields.data[i]);
unsigned a = f->type->alignsize() - 1;
if (((f->offset + a) & ~a) != f->offset) {
return true;
}
if (f->type->toBasetype()->ty == Tstruct && hasUnalignedFields(f->type)) {
return true;
}
}
ts->unaligned = 1;
return false;
}
////////////////////////////////////////////////////////////////////////////////
size_t getMemberSize(Type *type) {
const dinteger_t dSize = type->size();
llvm::Type *const llType = DtoType(type);