================
@@ -16983,6 +16983,26 @@ void Sema::DiscardMisalignedMemberAddress(const Type
*T, Expr *E) {
}
}
+/// If packing reduces \p FD below the alignment required by its type, return
+/// the alignment it is reduced to. __attribute__((packed)) reduces every
+/// field; #pragma pack(N) only reduces fields that require more than N.
+static std::optional<CharUnits> getPackedFieldAlignment(const ASTContext &Ctx,
+ const FieldDecl *FD) {
+ const RecordDecl *RD = FD->getParent();
+ bool IsPacked = FD->hasAttr<PackedAttr>() || RD->hasAttr<PackedAttr>();
+ const auto *MFAA = RD->getAttr<MaxFieldAlignmentAttr>();
+ if (!IsPacked && !MFAA)
+ return std::nullopt;
+
+ CharUnits TypeAlignment = Ctx.getTypeAlignInChars(FD->getType());
+ if (!IsPacked &&
+ Ctx.toCharUnitsFromBits(MFAA->getAlignment()) >= TypeAlignment)
+ return std::nullopt;
----------------
mattst88 wrote:
Included it. A typedef that lowers alignment now counts like packing, so
`g23`'s `inner` is the culprit directly and the fallback is gone. A struct with
no packing at all is also diagnosed when its member chain goes through such a
typedef.
Looking at this I also found `-fpack-struct` and `#pragma options align=mac68k`
reduce alignment without leaving a `MaxFieldAlignmentAttr`, so I covered those
too, along with the Microsoft layout ignoring `#pragma pack` wider than a
pointer. Tests are in `address-packed-layout.c`.
The warning text still says "packed member" for all of these. I can reword it
in a follow-up if you'd like.
https://github.com/llvm/llvm-project/pull/219096
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits