================ @@ -389,14 +389,28 @@ void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) { // Empty fields have no storage. ++Field; } else { - // Use base subobject layout for the potentially-overlapping field, - // as it is done in RecordLayoutBuilder - Members.push_back(MemberInfo( - bitsToCharUnits(getFieldBitOffset(*Field)), MemberInfo::Field, - Field->isPotentiallyOverlapping() - ? getStorageType(Field->getType()->getAsCXXRecordDecl()) - : getStorageType(*Field), - *Field)); + CharUnits CurOffset = bitsToCharUnits(getFieldBitOffset(*Field)); + llvm::Type *StorageType = getStorageType(*Field); + + // Detect cases when the next field needs to be packed into tail padding + // of a record field. This is typically caused by [[no_unique_address]], + // but we try to infer when that is the case rather than checking for the + // attribute explicitly because the attribute is typically not present in + // debug info. Use the base subobject LLVM struct type in these cases, + // which will be less than data size bytes. + if (const CXXRecordDecl *FieldRD = + Field->getType()->getAsCXXRecordDecl()) { + CharUnits NextOffset = Layout.getNonVirtualSize(); + auto NextField = std::next(Field); ---------------- rnk wrote:
That is annoying. I think the whole purpose of building the `Members` vector is to sort the subobjects by offset to avoid dealing with special cases where field offsets are non-ascending, so perhaps I should be computing the LLVM storage types in a second pass altogether. https://github.com/llvm/llvm-project/pull/122197 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits